加载iOS应用程序后更改根视图控制器。

时间:2013-08-14 08:04:44

标签: ios viewcontroller uistoryboardsegue appdelegate

为了在应用加载时显示我的登录屏幕,而不是在用户登录后显示,我决定在用户​​成功登录时在NSUserDefaults中添加auth对象。当应用程序启动时,检查auth参数,并相应地设置视图控制器(如果用户是auth它将显示一个feed,如果没有它将显示一个登录屏幕)在后一种情况下,我有app委托在用户登录后将根视图控制器重置为源。这是不好的做法还是更好的方法?

app delegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary     *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    IIViewDeckController* deckController = [self generateControllerStack];
    self.rightController = deckController.rightController;
    self.centerController = deckController.centerController;

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

    if([[defaults objectForKey:@"auth"] isEqualToNumber:[NSNumber numberWithInt:1]]){
        self.window.rootViewController = deckController;
    }else{
        UIStoryboard *sb = [UIStoryboard storyboardWithName:@"MainStoryboard"
                                                 bundle:nil];
        UIViewController* vc = [sb instantiateViewControllerWithIdentifier:@"loginViewController"];
        self.window.rootViewController = vc;
    }
    [self.window makeKeyAndVisible];
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackOpaque animated:NO];
    return YES;
}

- (void) setRoots
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    IIViewDeckController* deckController = [self generateControllerStack];
    self.rightController = deckController.rightController;
    self.centerController = deckController.centerController;
    self.window.rootViewController = deckController;
    [self.window makeKeyAndVisible];
}

登录视图控制器

- (IBAction)loginClick:(id)sender {
    if([_emailField.text length]>0&&[_passField.text length]>0){
        NSString *user = _emailField.text;
        NSString *pass = _passField.text;
        [[API sharedInstance] login:user andPass:pass onCompletion:^(NSDictionary *json){
            NSLog(@"%@", json);
            if(![json objectForKey:@"error"]){
                [API sharedInstance].authorized = 1;
                NSNumber *auth = [NSNumber numberWithInt:1];
                NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
                [defaults setObject:auth forKey:@"auth"];
                [defaults synchronize];

                captureYouAppDelegate *app = [[UIApplication sharedApplication] delegate];
                [app setRoots]; 
            }else{
                [API sharedInstance].authorized = 0;
            }
        }];
    }else{
        if([_emailField.text length]<1){
            [_emailField becomeFirstResponder];
        }else{
            [_passField becomeFirstResponder];
        }
    }
}

我想知道是否有比这更好或更容易的方式。谢谢!

4 个答案:

答案 0 :(得分:6)

只是澄清一下。我之前没有任何问题重置了UIWindow的rootViewController,但是当试图在允许设备轮换的同时尝试这样做时,我遇到了一些问题 - 旋转刚刚停止工作。

我在尝试调试时直接从Apple的文档中找到了以下内容。以下链接提供了许多有关使用UIWindow的指南。这些都与设备轮换有关,但仍然有待了解。

简短回答,使用根控制器并添加子视图控制器。然后,您可以毫无问题地换出子VC。

  

•您已将视图控制器的UIView属性添加到UIWindow作为子视图。

     

不鼓励开发人员将任何视图控制器的视图属性添加为UIWindow的子视图。应用程序的根视图控制器应该在Interface Builder中分配给应用程序窗口的rootViewController属性,或者在从应用程序返回之前在运行时分配:didFinishLaunchingWithOptions:。如果需要同时显示来自多个视图控制器的内容,则应定义自己的容器视图控制器并将其用作根视图控制器。请参阅创建自定义容器视图控制器。

查看this technical Q&A了解详情。

答案 1 :(得分:4)

我不认为重置window.rootViewController是一种不好的做法。但是,无需重新创建窗口  如果您不想使用以前的视图控制器,只需将窗口的rootViewController替换为新的视图控制器即可。如果您确实要切换回以前的视图控制器,请使用-presentViewController: animated: completion:来显示视图控制器,这可能是更好的选择。

答案 2 :(得分:0)

无需再次分配窗口,您可以直接设置此

window.rootViewController = yourVC;

答案 3 :(得分:0)

Step by Step我在UINavigationController的帮助下展示了使用rootviewcontroller的良好实践

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  
    // Override point for customization after application launch.

    self.splash = [[SplashViewController alloc] initWithNibName: @"SplashViewController" bundle: nil];  
    self.window.rootViewController = self.splash;  
    [self.window makeKeyAndVisible];  
    DLog(@"finished initializing .....");  
    [self setRootViewController];  

    return YES;  
}



- (void) setRootViewController  
{  
    DLog(@"setRootViewController");  
    if (self.sessionManager.isLoggedIn)  
    {  
            [self navigateToHomeController];  

    } else {  
            [self navigateToLoginController];  
      }  
}


- (void) navigateToHomeController  
{  
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"kStoryBoard" bundle: nil];  
    UINavigationController* homeNavigationController =  [storyboard instantiateViewControllerWithIdentifier:@"kHomeNavController"];  
    NSArray* controllers = [homeNavigationController viewControllers];  
    if([controllers lastObject])  
    {  
        if ([[controllers objectAtIndex:0] isKindOfClass:[HomeViewController class]]) {  
            HomeViewController* homeController = (HomeViewController*) [controllers objectAtIndex:0];  
            self.window.rootViewController = [[OLNavigationViewController alloc] initWithRootViewController: homeController]; 
        }  
    }  
}



- (void) navigateToLoginController  
{  
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"kStoryBoard" bundle: nil];  
    UINavigationController* loginNavigationController = [storyboard instantiateViewControllerWithIdentifier:@"kLoginNavController"];  
    if ([loginNavigationController isKindOfClass:[OLLoginViewController class]]) {  
        OLLoginViewController* loginController = (OLLoginViewController*) loginNavigationController;  
        loginController.shouldHideToolBar = YES;  
        self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController: loginController];  
    }
}