iOS 编程:关于根视图控制器的说明
Posted
技术标签:
【中文标题】iOS 编程:关于根视图控制器的说明【英文标题】:Programming iOS: clarifications about Root View Controller 【发布时间】:2011-04-30 13:36:32 【问题描述】:通过这个问题,我想知道我是否理解根视图控制器的概念。
在 ios 应用程序中,根视图控制器 (RVC) 是其视图在启动时添加到 UIWindow 应用程序的控制器,不是吗?
[window addSubview:rvcController.View];
[window makeKeyAndVisible];
现在,一个 UIWindow 也有一个 rootViewController 属性。在运行之前的 sn-p 代码时,该属性是填充了 rvcController 还是我必须显式设置它?
然后,在 UINavigationController 中,可以设置与之前为入口点设置的 RVC 不同的 RVC。
在这种情况下,我第一次将控制器添加到 navigationController 堆栈(在其上推送新控制器)时,框架是否将该控制器设置为 navigationController 的 RVC,或者我是否必须通过 @987654322 显式设置它@方法?
【问题讨论】:
【参考方案1】:是的.. 当我开始 iPhone 开发时.. rootViewController 的事情也让我陷入了循环。但这真的很简单。
当应用程序启动时,我在我的应用程序委托类中创建了一个 UIWindow 对象。另外,在那个类中,我有一个 UIWindow 类型的属性,称为 window;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
UIWindow *w = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
self.window=w;
[w release];
// other code here...
然后我创建一个UIViewController
,其view
将是窗口层次结构中的第一个视图,这可以称为“根视图控制器”。
令人困惑的部分是……我们经常创建一个UINavigationController
作为“根视图控制器”,并且导航控制器有一个 init 方法请求一个“RootViewController”,这是它将放置的第一个视图控制器它的堆栈。
因此,窗口获得了一个“根视图控制器”,即UINavigationController
,它还有一个RootViewController,这是您要显示的第一个视图控制器。
一旦你把它弄明白了,一切都说得通了。我认为:-)
这里有一些代码可以完成所有工作..(取自我面前打开的一个项目)
//called with the app first loads and runs.. does not fire on restarts while that app was in memory
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
//create the base window.. an ios thing
UIWindow *w = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
self.window=w;
[w release];
// this is the home page from the user's perspective
//the UINavController wraps around the MainViewController, or better said, the MainViewController is the root view controller
MainViewController *vc = [[MainViewController alloc]init];
UINavigationController *nc = [[UINavigationController alloc]initWithRootViewController:vc];
self.navigationController=nc; // I have a property on the app delegate that references the root view controller, which is my navigation controller.
[nc release];
[vc release];
//show them
[self.window addSubview:nc.view];
[self.window makeKeyAndVisible];
return YES;
【讨论】:
但这并没有设置window.rootViewController,是吗? “相对较新”的属性 window.rootViewController(从 4.0 开始)确实将其添加到窗口层次结构中并持有对 Windows 根视图控制器的引用。 对,所以,我没有看到它被设置,VC 是通过[self.window addSubview:nc.view];
添加的,所以这个例子不会设置它,对吧?
从今天的角度来看(iOS 6),唯一的变化是调用“window.rootViewController = nc”而不是“self.window addSubview:nc.view]”吗?【参考方案2】:
现在,一个 UIWindow 也有一个 rootViewController 属性。在运行之前的 sn-p 代码时,该属性是填充了 rvcController 还是我必须明确设置它?
您必须明确设置它,如果这样做,您可以删除 addSubview
行,因为设置根视图控制器时会自动处理。
然后,在 UINavigationController 中,可以设置与之前为入口点设置的 RVC 不同的 RVC。
当然,导航控制器的根视图控制器与窗口的根视图控制器无关。
在这种情况下,我第一次将控制器添加到 navigationController 堆栈(在其上推送新控制器)时,框架是否将该控制器设置为 navigationController 的 RVC,或者我是否必须通过 initWithRootViewController 方法显式设置它?
initWithRootViewController 只是初始化空导航控制器并将第一个(根)视图控制器推入堆栈的快捷方式。请注意rootViewController
不是UINavigationController
的属性,您可以通过[navController.viewControllers objectAtIndex:0]
访问它。
【讨论】:
感谢您的回复 omz。 您必须明确设置它是什么意思,如果这样做,您可以删除 addSubview 行,因为在设置根视图控制器时会自动处理。? 那你说initWithRootViewController
是一种快捷方式。行!所以用这个方法创建一个navigationController或者新建一个然后push一个控制器,都是一样的,不是吗?这两个过程是否都创建了我无法删除的根视图控制器?
非常感谢您的合作!!
如果向窗口添加子视图,rootViewController 属性不会自动填充。您可以删除导航控制器的根视图控制器,它只是数组中第一个可以为空的元素(尽管它应该只是暂时为空)。
非常感谢 omz。还有2个问题给你。 1) 为 UIWindow 设置 rootViewController 属性,它还允许将视图添加到窗口中,可以吗?但是如果我不设置 rootViewController 属性,会发生什么?并且一旦设置,窗口的 rootcontroller 属性是否可以与另一个删除?【参考方案3】:
首先你可以在 Xcode 中创建一个空项目。在使用 xiv 在objectivec 类视图控制器上添加新文件之后。现在您可以在 appdeligate.m 中添加此代码 并在 appdeligate 中设置 rootviewcontroller
注意:- ViewController.h 导入到 appdeligate.m
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
ViewController *viewcontroller =[[ViewController alloc]initWithNibName:@"ViewController" bundle:nil];
self.window.rootViewController= viewcontroller;
[self.window makeKeyAndVisible];
return YES;
【讨论】:
【参考方案4】: -(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
ViewController *viewcontroller =[[ViewController alloc]initWithNibName:@"ViewController" bundle:nil];
self.window.rootViewController= viewcontroller;
[self.window makeKeyAndVisible];
return YES;
【讨论】:
以上是关于iOS 编程:关于根视图控制器的说明的主要内容,如果未能解决你的问题,请参考以下文章
添加根视图控制器 OCMockObject[UIViewController] 作为子视图控制器错误