ios - Swift:子类化 UIViewController 的 Root View

标签 ios uiview uiviewcontroller swift

tl;dr:我如何告诉 Swift 我正在使用 UIView 的子类覆盖 MyViewControllerview 属性?


我想做什么

我非常喜欢为 UIViewController 的 View 提供 UIView 的子类。例如:

// MyView --------------------------------------------------------

@interface MyView: UIView
@property (nonatomic, strong) UITableView *tableView;    
@end

@implementation MyView

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        _tableView = [[UITableView alloc] initWithFrame:frame];
    }
    return self;
}

@end

// MyViewController ----------------------------------------------

@interface MyViewController: UIViewController <UITableViewDataSource>
@property (nonatomic, retain) MyView *view;
@end

@implementation MyViewController

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

- (void)viewDidLoad {
    [super viewDidLoad];

    self.view.tableView.dataSource = self;
    // etc.
}

@end

这很棒,因为它将 View 创建和布局逻辑与 View Controller 分开。好的,好的。

据我所知,这可以像这样转化为 Swift:

// MyView --------------------------------------------------------

class MyView: UIView {
    let tableView: UITableView!

    init(frame: CGRect) {
        super.init(frame: frame)
        tableView = UITableView(frame: frame)
    }
}

// MyViewController ----------------------------------------------

class MyViewController: UIViewController, UITableViewDataSource {
    override func loadView() {
        view = MyView(frame: UIScreen.mainScreen().bounds)
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // this causes the compiler to complain with:
        // 'UIView' does not have a member named 'tableView'
        self.view.tableView.dataSource = self
    }
}

问题是我似乎无法弄清楚如何告诉 View Controller 它的 viewMyView 而不是 UIView本身。

失败的尝试

这是我到目前为止尝试过的:

我在 MyViewController 的顶部试过这个,但出现以下错误:

override var view: MyView!
// error: Cannot override mutable property 'view' of
//        type 'UIView' with covariant type 'MyView!'

我已经在 loadView 中试过了,但没有成功:

view = MyView(frame: UIScreen.mainScreen().bounds) as MyView
// this produces the same error as in the original code:
// 'UIView' does not have a member named 'tableView'

问题来了

我如何告诉 Swift 我正在用 MyView 的子类之一覆盖 MyViewControllerview 属性?这可能吗?如果不是,为什么不呢?

最佳答案

我认为在 Swift 中可能无法实现完全相同的实现。来自 Swift 书中关于覆盖属性的部分:

“You must always state both the name and the type of the property you are overriding, to enable the compiler to check that your override matches a superclass property with the same name and type.”

但是,您可以使用计算属性返回 View Controller 的 view 属性的类型转换版本,它几乎一样干净:

class MyViewController: UIViewController, UITableViewDataSource {
    var myView: MyView! { return self.view as MyView }

    override func loadView() {
        view = MyView(frame: UIScreen.mainScreen().bounds)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        self.myView.tableView.dataSource = self
    }
}

关于ios - Swift:子类化 UIViewController 的 Root View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24131627/

相关文章:

ios - 登录 Twitter 有时会失败

ios - 使用 facebook-ios-sdk 登录时如何访问 appDelegate 中的另一个 UIViewController?

ios - 为什么 webview 不适合所有 View ?

ios - UIview 起始中心看似不正确。 (虚假视觉)

ios - 开始输入时出现的 View ,iOS

objective-c - UIView 大小不符合预期

ios - UIView 不显示在给定的框架中

ios - iPad UIViewController 复杂界面最佳实践

ios - 无法识别侧边栏实例的选择器

ios - 动画正在进行时访问表示层崩溃