29

我有一个自定义 UIViewController 和自定义 UIView。我想覆盖 viewcontroller.view 属性以返回 MyCustomUIView。

现在我有:

@interface MyViewController : UIViewController {    
    IBOutlet MyView* view;
}

@property (nonatomic, retain) IBOutlet MyView* view;

这可以编译,但我收到警告:属性“视图”类型与超类“UIViewController”属性类型不匹配。

如何缓解此警告?

4

5 回答 5

23

@lpaul7 已经发布了 Travis Jeffery 博客的链接作为评论,但它比所有其他答案更正确,它确实需要代码作为答案:

视图控制器.h:

@interface ViewController : UIViewController

@property (strong, nonatomic) UIScrollView *view;

@end

视图控制器.m:

@implementation ViewController

@dynamic view;

- (void)loadView {
  self.view = [[UIScrollView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
}

@end

如果您使用 xib,而不是覆盖loadView更改视图控制器的根视图的类型并添加IBOutlet到属性中。

有关详细信息,请参阅重写 UIViewController 的 View 属性,正确完成

于 2013-05-07T16:03:34.210 回答
18

简短的回答是你没有。原因是属性实际上只是方法,如果你试图改变返回类型,你会得到:

  • (UIView *) 视图;
  • (我的视图 *)视图;

Objective-C不允许返回类型协变。

您可以做的是添加一个新属性“myView”,并使其简单地对“view”属性进行类型转换。这将减轻整个代码中的类型转换。只需将您的视图子类分配给视图属性,一切都会正常工作。

于 2009-03-14T19:48:22.027 回答
4

UIViewController 的视图属性/方法将自动返回您的视图。我认为您只需将结果转换为 MyView (或仅使用 id 类型):

MyView *myView = (MyView*)controller.view;
id myView = controller.view;

我认为您在上面发布的代码会给您带来麻烦。您可能不想自己创建视图成员(因为控制器将存储 2 个视图,并且可能不会在内部使用正确的视图)或覆盖视图属性(因为 UIViewController 对其进行了特殊处理。)(请参阅此有关后者的更多信息的问题。)

于 2009-03-14T19:49:38.637 回答
4

对不起,但你的简短回答是错误的。

正确的实现是使用您的返回类型将@property 添加到头文件。然后手动添加 getter 和 setter 而不是 @synthesize,并从 [super view] 返回一个强制转换类型

例如我的类是 PlayerViewController

播放器视图控制器.h

@property (strong, nonatomic) IBOutlet PlayerView *view;

播放器视图控制器.m

- (PlayerView *)view{
    return (PlayerView*)[super view];
}
- (void)setView:(PlayerView *)view{
    [super setView:view];
}

重要的是把正确的类放到视图中。

将 UIView 放在 PlayerView 所在的位置可能会在 Interface Builder 中工作,但在代码中无法正常运行。

我目前正在使用这个实现。

于 2012-04-25T22:35:23.657 回答
0

如果有人使用 Swift 2.0+,您可以使用协议扩展来实现可重用:

// 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
于 2015-10-14T04:19:17.297 回答