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 编程:关于根视图控制器的说明的主要内容,如果未能解决你的问题,请参考以下文章

关于 iOS 照片应用中的视图控制器

添加根视图控制器 OCMockObject[UIViewController] 作为子视图控制器错误

以编程方式设置为根视图控制器时,视图控制器无法正确显示子视图

关于 UITable 视图的异常

如何以编程方式设置根视图控制器?

更改 iOS 窗口的根视图控制器