self.window.rootViewController与window addSubview的区别

51
我注意到在应用程序委托中有许多 iPhone 应用程序的示例:
- (void)applicationDidFinishLaunching:(UIApplication *)application
其中,
[window addSubview: someController.view]; (1)

self.window.rootViewController = self.someController; (2)
相对应。
是否有使用其中一种方法的实际原因?哪一个技术上是正确的?控制器是否有类似于(2)的等效命令,例如:
self.someController.rootController = self.someOtherController; // 伪代码
4个回答

51

UIWindowrootViewController属性在iOS4中推出。

旧的技术是使用addSubview方法。

新的、推荐的技术是设置rootViewController属性。


7
为什么推荐使用设置rootViewController而不是addSubview? - pepsi
1
@pepsi 我可以告诉你,在 iOS 5.0 上,它更有意义,由于 NDA 的限制,我们不能在这里讨论它,请在开发者论坛上询问,你会得到答案,它与视图控制器包含有关。 - Zebs
1
一个可以争议的好处是,作为属性,你可以在IB中设置它,而不是编写代码来执行关联。 - TomSwift
2
不要合并这两种技术!这会导致奇怪的行为,有时会导致自动旋转停止工作。 - Paul N
在iPad上创建新的游戏中心账户时,rootViewController无法正常工作 - 底层视图会消失。当主视图使用addSubview添加时,同样的操作可以正常工作。 - rasmus

10

关于ios 6的发布,此处进行更新。

如果仍在使用 -[UIWindow addsubview:] 模板,现在您可能还会在控制台中看到消息“应用程序窗口在应用程序启动时应具有根视图控制器”,以及您的应用程序可能存在潜在的旋转和布局问题。

按照上文设置窗口的 rootViewController 也将修复这个问题。


是的,即使ViewController使用了新的iOS6旋转API,我的视图仍然以错误的方向显示...直到我修复了这个问题! - mattorb
天哪!我已经看到这个消息好几周了,一直找不到合适的解决方案,直到现在我不再寻找时才找到了!谢谢。 - Duck

5
我使用这段代码:
    rootViewController_ = [[RootViewController alloc] initWithFrame:[UIScreen mainScreen].bounds];
    window_ = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    if ([window_ respondsToSelector:@selector(setRootViewController:)]) { // >= ios4.0
        [window_ setRootViewController:rootViewController_];
    } else { // < ios4.0
        [window_ addSubview:rootViewController_.view];
    }

1

我的观点:

self.window.rootViewController 会根据状态栏的高度调整rootViewController.view的大小。

但是如果您使用addSubview,它不会这样做。

例如,如果您将RootViewController设置为NavigationController,则navigationController将为(0,0,320,480);

但是如果您将RootViewController设置为普通的UIViewController,则navigationController将为(0,0,320,460);

如果您使用addSubview,则两个视图控制器将为(0,0,320,480)

如果有一个呼叫状态栏,当您使用setRoot...时,它也会为您更改。如果您使用addSubview,则子视图大小不会更改

使用不同的视图边框颜色进行一些测试


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接