How do I override the “view” property in UIViewController?
我有一个自定义的uiview控制器和自定义的uiview。我想重写ViewController.View属性以返回MyCustomUIView。
现在我有:
1 2 3 4 5 | @interface MyViewController : UIViewController { IBOutlet MyView* view; } @property (nonatomic, retain) IBOutlet MyView* view; |
这会编译,但我收到警告:属性"view"类型与超级类"uiviewcontroller"属性类型不匹配。
如何减轻这种警告?
@lpaul7已经发布了一个到travis jeffery博客的链接作为评论,但是它比所有其他答案都更正确,因此它真正需要代码作为答案:
视图控制器.h:
1 2 3 4 5 | @interface ViewController : UIViewController @property (strong, nonatomic) UIScrollView *view; @end |
视图控制器.m:
1 2 3 4 5 6 7 8 9 | @implementation ViewController @dynamic view; - (void)loadView { self.view = [[UIScrollView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]]; } @end |
如果使用XIB,而不是重写
有关更多详细信息,请参见重写uiviewcontroller的视图属性(右完成)。
简短的回答是,您没有。原因是属性实际上只是方法,如果您试图更改返回类型,则会得到:
- (UIVIEW *)观点;
- (MyVIEW *)观点;
Objective-C不允许返回类型协方差。
您可以做的是添加一个新的属性"myview",并使其简单地类型化"view"属性。这将减轻整个代码中的类型转换。只需将视图子类分配给视图属性,一切都会正常工作。
对不起,你的简短回答是错的。
正确的实现方法是将@property添加到具有返回类型的头文件中。然后手动添加getter和setter,并从[super view]返回强制类型,而不是@synthesis。
例如,我的类是一个playerview控制器
播放视图控制器.h
1 | @property (strong, nonatomic) IBOutlet PlayerView *view; |
播放视图控制器.m
1 2 3 4 5 6 | - (PlayerView *)view{ return (PlayerView*)[super view]; } - (void)setView:(PlayerView *)view{ [super setView:view]; } |
重要的是将正确的类放入视图中。
将一个uiview放在playerview所在的位置在接口构建器中可能会工作,但在代码中不会正常工作。
我目前正在使用这个实现。
uiviewController的视图属性/方法将自动返回视图。我认为您只需要将结果强制转换为myview(或使用id类型):
1 2 | MyView *myView = (MyView*)controller.view; id myView = controller.view; |
我认为你上面发布的代码会给你带来麻烦。您可能不想自己创建视图成员(因为这样控制器将存储2个视图,并且可能在内部不使用正确的视图成员)或重写视图属性(因为uiviewcontroller对其有特殊的处理。)(有关后者的详细信息,请参见此问题。)
如果有人在Swift2.0+上,您可以使用协议扩展来实现可重用的实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | // Classes conforming to this protocol... protocol CustomViewProvider { typealias ViewType } // ... Will get customView accessor for free extension CustomViewProvider where Self: UIViewController, Self.ViewType: UIView { var customView: Self.ViewType { return view as! Self.ViewType } } // Example: extension HomeViewController: CustomViewProvider { typealias ViewType = HomeView } // Now, we can do something like let customView: HomeView = HomeViewController().customView |