我希望这是一个简单的问题。如果我有一个UINavigationController并且我将一个新的视图控制器推入到具有动画过渡的堆栈中,我如何检测动画何时完成并且新的视图控制器在屏幕上?
我有几个场景,我需要推送一个新的控制器,然后必须进行长时间运行。我想首先推送新视图,所以在我开始长时间阻止主线程之前屏幕上有一些东西。如果我在我的长期运行任务之后立即执行推送,则视图将不会显示,直到两者完成后,主线程才能再次处理事件。
因此,一旦动画完成并且视图在屏幕上,我想要做的就是能够在新控制器中检测到,然后启动任务。
答案 0 :(得分:21)
+1 @ DHamrick建议不要阻止主线程。
要回答原始问题,您可以在两个位置检测viewController更改:
您刚刚推送的viewController将收到viewWillAppear:和viewDidAppear:条消息。如果您想知道特定viewController何时出现,请实现这些方法。
@Mike Z提到的navigationController:didShowViewController:animated:
方法被发送到navigationController的delegate。您需要将对象指定为该委托才能接收此消息。然后,您将知道每个时间viewController出现。
答案 1 :(得分:4)
您应该使用GCD队列,而不是阻止主线程,而是在另一个线程内部进行长时间运行,甚至更好。
dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, NULL);
dispatch_async(backgroundQueue, ^{
// Do your long running code
dispatch_async(dispatch_get_main_queue(), ^{
//Update your UI
});
});
您可以将此代码放在viewDidLoad:
中,以便了解您的用户界面已加载。这也意味着您不必依赖动画的时间。
答案 2 :(得分:3)
我自己没有测试或实现过,但文档听起来像是:
navigationController:didShowViewController:animated:
描述为:在导航控制器显示视图控制器的视图和导航项属性后立即发送到接收器。
否则,
setAnimationDidStopSelector:
可能适合您。
描述为:设置动画停止时发送给动画代表的消息。