如何将视图控制器推送到iOS中标签栏中的导航控制器

时间:2014-02-07 22:26:32

标签: ios cocoa-touch cocoa uinavigationcontroller uistoryboard

我有一个标签栏控制器,每个标签都有一个导航控制器。导航控制器具有视图控制器。然后,如果用户需要登录或注销,我的登录控制器没有连接到我用以下代码调用的标签栏控制器。

当我尝试根据用户是否登录时有条件地推送视图控制器时,我看到一些奇怪的行为。

我的逻辑看起来像这样:

if(currentUser){
}else{

        LoginViewController *svc = [self.storyboard instantiateViewControllerWithIdentifier:@"Login"];
        svc.hidesBottomBarWhenPushed = YES;
        [self.navigationController pushViewController:svc animated:YES];

    }

当推送视图时,看起来好像已经按下了登录视图,并且在其上推送了另一个登录视图。

对于注销,我在segue中有相同的代码:

if ([segue.identifier isEqualToString:@"LogoutView"]) {

        [self logOut];
        LoginViewController *svc = [self.storyboard instantiateViewControllerWithIdentifier:@"Login"];
        svc.hidesBottomBarWhenPushed = YES;
        [self.navigationController pushViewController:svc animated:YES];
    }

在这个例子中,我看到相同的双推,每次我点击我的登录按钮时,它会推送另一个登录视图。这种情况无限发生。然后我收到警告:

  

在意外状态下完成导航转换。   导航栏子视图树可能已损坏。

当我在导航中按回来时,应用程序崩溃并显示错误:

  

NSInvalidArgumentException',原因:'无法将自己添加为子视图'

我没有正确推送登录视图控制器吗?

1 个答案:

答案 0 :(得分:2)

Segues实例化新控制器,并执行从源控制器到目标控制器的转换。因此,您既不应该在代码中实例化控制器,也不应该使用pushViewController推送它:animated:。如果按钮(而不是控制器)正在触发segue,那么您只需要获取对目标控制器的引用(segue.destinationViewController),并使用它来隐藏底栏,

-(void)prepareForSegue:(UIStoryboardSegue *) segue sender:(id) sender {

    if ([segue.identifier isEqualToString:@"LogoutView"]) {

            [self logOut];
            LoginViewController *svc = segue.destinationViewController;
            svc.hidesBottomBarWhenPushed = YES;
    }
}

如果您需要有条件地执行此操作,则应直接从控制器连接segue,而不是按钮。然后你需要调用performSegueWithIdentifier:在某种方法中你有逻辑来确定应该执行哪个(或者是否)segue。