1)创建导航控制器和3个视图控制器。
firstViewController.m:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSLog(@"DEBUG: first screen did appear");
[self.navigationController pushViewController:[self.storyboard instantiateViewControllerWithIdentifier:@"secondScreen"] animated:NO];
}
secondViewController.m:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSLog(@"DEBUG: second screen did appear");
[self.navigationController pushViewController:[self.storyboard instantiateViewControllerWithIdentifier:@"thirdScreen"] animated:YES];
}
thirdViewController.m:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSLog(@"DEBUG: third screen did appear");
}
2)使firstViewController
(也就是故事板中的firstScreen)导航控制器的根视图控制器。
3)运行应用并注意导航栏已更新以显示第三个屏幕的标题,但仍显示第二个屏幕的内容。
我尝试使用UINavigationControllerDelegate
的{{1}}方法,因为它似乎在-( void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
方法之后触发,但它没有解决问题。
我还尝试手动设置导航控制器的viewDidAppear
,认为它会跳过一些“此视图控制器处于活动状态”逻辑并允许有问题的推送工作,但事实并非如此。
我能想出的唯一解决方案是使用延迟调用在 secondViewController.m 中推送所需的视图控制器:
viewControllers
我想了解为什么这不能按预期工作。基于我在半相关问题上看到的其他一些SO答案,它可能与运行循环有关,但我无法确认或否认(似乎可能因为调度推送允许它工作)。 / p>
能有更多知识/经验的人能够启发我吗?
谢谢!
答案 0 :(得分:3)
这是一个有趣的问题。我非常有信心,如果您在 firstViewController.m 中推送第二个视图控制器时设置animated:YES
,则最终 UI状态将显示为预期,第三个屏幕的内容和标题都正确可见。
但是,这显然不是您所瞄准的过渡效果。为什么animated
旗帜无论如何都会产生差异呢?
如果您在-viewDidAppear:
中设置了一个断点,并查看了animated == YES
和animated == NO
的情况下的堆栈跟踪,那么它就像animated == NO
时一样,在-viewDidAppear:
的视图布局操作期间调用UINavigationController
。我的钱就是因为你的最终观点看起来不正确;现在执行推送将在前一次推送完成之前完成。
这就是运行循环考虑因素的来源。我们希望UINavigationController
的视图布局(在主运行循环的当前循环周期中发生)在要求之前完成下一步推。实现这一目标的一种简单方法是将推送排队到主运行循环的 next 循环。延迟肯定会起作用(我相信延迟0
足以延迟到下一个运行循环周期,因此您可以尝试用250 * USEC_PER_SEC
替换0
。另一种方法是将操作分配到主队列:
dispatch_async(dispatch_get_main_queue(), ^{
[self.navigationController pushViewController:[self.storyboard instantiateViewControllerWithIdentifier:@"thirdScreen"] animated:YES];
});
所以我的答案有点推测,但基于一些证据。在执行UINavigationController
转换时,-viewDidAppear:
仅表示动画过渡时的真实结束,但感觉似乎确实如此。感觉有点令人不满意。
答案 1 :(得分:0)
不确定为什么这不起作用,可能与时间有关。但是,要将多个视图控制器推送到导航控制器,首选方法是使用setViewControllers:animated:
NSMutableArray *viewControllers = [NSMutableArray arrayWithArray:[navigationController viewControllers]];
[viewControllers addObjectsFromArray:viewControllersToPush];
[navigationController setViewControllers:viewControllers animated:YES];