在iPad上,当一个控制器正在消失时呈现另一个控制器的UINavigationController。

3

我有一个视图需要用户登录。当用户尝试打开该视图并且未登录时,我将调用登录视图让他登录,完成后我将调用他原本想要查看的视图。
在iPhone上,我通过推送视图控制器来实现这一点,但在iPad上,使用呈现视图控制器就无法实现。它会显示“正在解除”,无法显示新控制器。以下是代码:

- (void) buttonPressed
{
    if (!userLoggedIn) { // userLoggedIn getter calls new screens of login if needed
    return;  // this is executed if user declined to login
    }
    MyViewController *temp = [[MyViewController alloc] init];
    [self.navigationController presentViewController:temp animated:YES]; // this returns warning that dismissal in progress and does not work
}

我该怎么办?在iPhone上,我的所有逻辑都能正常工作,但在iPad上却失败了。我在许多地方都使用它,完全重写代码是不好的。

编辑:更多代码:

- (BOOL) userLoggedIn {
   // code omitted
    [centerController presentViewController:navController animated:YES completion:nil];
   // code omitted
   [centerController dismissViewController:navController animated:YES]; // setting to NO does not fix my problem
   return YES;
}

编辑2: 这是iPad的代码。我已经删除了iPhone相关的代码。在iPhone上它所做的是使用推送而不是呈现控制器,在那种情况下一切正常。


我认为你使用了两个XIB,一个用于iPad,另一个用于iPhone,这是正确的吗? - Jitendra
更多的代码会很有用,以便查看正在推送什么和何时推送。 - occulus
你已经给这个标签打上了modalviewcontroller。这里实际涉及到模态性,还是只是使用了UINavigationController? - occulus
看了你的额外代码(谢谢),我认为我发布的答案正是你所需要的。 - occulus
@occulus presentViewController是一种以模态方式呈现视图控制器的方法。presentModalViewController已经被弃用,应使用此方法代替。 - Dvole
显示剩余2条评论
2个回答

3
只有在您的第一个视图解散完成之后,才能呈现另一个视图。应该在呈现新视图之前完成解散视图的动画。因此,您可以在解散时将其动画设置为NO,或使用performSelector:withObject:afterDelay:并在2-3秒后呈现下一个视图。
希望这可以帮助您。

使用performSelector:withObject:afterDelay:来进行这种用法会导致应用程序出现竞争条件,并且也不是理想的用户体验。 - occulus
也许更好的方法是在dismiss选择器中使用完成块 [self dismissViewControllerAnimated:YES completion:^{.....}]; 来呈现另一个控制器。 - yonel

2

您没有发布足够的代码以真正了解您正在做什么,但解决在消除和推送视图控制器方面发生冲突的问题的一种方法是将pop+push转换为单个原子操作,而不是顺序操作。

您可以通过在UINavigationController上使用setViewControllers:animated:方法来实现此操作。这使您能够有效地删除一个或多个视图控制器,并添加一个或多个视图控制器,所有这些都作为一个连贯的操作进行,具有一个无缝的动画效果。

这是一个简单的示例:

[self.navigationController pushViewController:loginController];

// ... later on, when user login is validated:
NSMutableArray *viewControllers = 
    [self.navigationController.viewControllers copy];

[viewControllers removeLastObject];

[viewControllers addObject:[[MyNewViewController alloc] init]];

[self.navigationController setViewControllers:viewControllers animated:YES];

如果您按照这种方式进行操作,您的代码将更加可预测,并且可以在iPhone和iPad上运行。
有关更多信息,请参见API文档更新 由于您的问题涉及顶部的模态对话框,请尝试在关闭模态对话框之前使用setViewControllers:animated:NO来更改模态登录对话框下面的导航控制器堆栈。

很遗憾,由于设计问题,我无法在iPad上推送控制器。我需要将登录控制器作为模态窗口,然后将其关闭并将新的控制器作为模态窗口。 - Dvole
你尝试过在不使用动画的情况下,在模态视图消失之前更改模态视图下方的导航控制器堆栈吗?例如,使用setViewControllers:animated:NO。 - occulus

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