关于iphone:如何覆盖UIViewController中的“view”属性?

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,而不是重写loadView,请更改视图控制器根视图的类型,并将IBOutlet添加到属性中。

有关更多详细信息,请参见重写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