我有一个自定义的UIViewController和自定义UIView。我想重写viewcontroller.view属性以返回MyCustomUIView。
现在我有:
@interface MyViewController : UIViewController {
IBOutlet MyView* view;
}
@property (nonatomic, retain) IBOutlet MyView* view;
这个编译但我得到一个警告:属性'view'类型与超类'UIViewController'属性类型不匹配。
如何缓解此警告?
答案 0 :(得分:23)
@ lpaul7已经发布了一条链接到Travis Jeffery的博客作为评论,但它比所有其他答案更正确,它确实需要代码作为答案:
<强> ViewController.h:强>
@interface ViewController : UIViewController
@property (strong, nonatomic) UIScrollView *view;
@end
<强> ViewController.m:强>
@implementation ViewController
@dynamic view;
- (void)loadView {
self.view = [[UIScrollView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
}
@end
如果使用xib,而不是覆盖loadView
,请更改视图控制器根视图的类型,并将IBOutlet
添加到属性中。
有关详细信息,请参阅Overriding UIViewController's View Property, Done Right。
答案 1 :(得分:18)
简短的回答是你没有。原因是属性实际上只是方法,如果你试图改变返回类型,你得到这个:
Objective-C 不允许返回类型协方差。
您可以做的是添加一个新属性“myView”,并简单地将其视为“view”属性。这将减轻整个代码中的类型转换。只需将视图子类分配给view属性,一切都可以正常工作。
答案 2 :(得分:4)
UIViewController的view属性/方法将自动返回您的视图。我想你只需要将结果转换为MyView(或者只是使用id类型):
MyView *myView = (MyView*)controller.view;
id myView = controller.view;
我认为您上面发布的代码会给您带来麻烦。您可能不希望自己创建一个视图成员(因为控制器将存储2个视图,并且可能不会在内部使用正确的视图)或覆盖视图属性(因为UIViewController对它有特殊处理。)(参见{ {3}}有关后者的更多信息。)
答案 3 :(得分:4)
很抱歉,但您的简短回答是错误的。
正确的实现方法是使用返回类型将@property添加到头文件中。 然后代替@synthesize,手动添加getter和setter,并从[super view]返回一个强制转换类型
例如我的类是一个PlayerViewController
PlayerViewController.h
@property (strong, nonatomic) IBOutlet PlayerView *view;
PlayerViewController.m
- (PlayerView *)view{
return (PlayerView*)[super view];
}
- (void)setView:(PlayerView *)view{
[super setView:view];
}
重要的是将正确的类放入视图中。
将UIView置于PlayerView所在的位置可能会在Interface Builder中起作用,但在代码中无法正常运行。
我目前正在使用此实现。
答案 4 :(得分:0)
如果有人使用Swift 2.0+,您可以使用协议扩展来实现可重用的实现:
margin-right: 1%