我希望这是一个简单的问题。如果我有一个UINavigationController,并且我将一个新的视图控制器推送到带有动画过渡的堆栈上,我如何检测动画何时完成并且新的视图控制器何时出现在屏幕上?
我有几种情况需要推送一个新控制器,然后必须执行长时间运行的操作。我想先推送新视图,以便在我开始长时间阻塞主线程之前屏幕上有一些东西。如果我在长时间运行的任务之后立即执行推送,则视图不会显示,直到两者都完成并且主线程能够再次处理事件。
所以,我想做的是能够在动画完成并且视图在屏幕上后在新控制器中检测到,然后开始任务。
+1 到 @DHamrick 的建议,根本不阻塞主线程。
要回答原始问题,您可以在两个位置检测 viewController 更改:
-
您刚刚推送的 viewController 将收到 viewWillAppear: 和 viewDidAppear: 消息。 如果想知道特定视图控制器何时出现,请实现这些方法。
-
@Mike Z 提到的
navigationController:didShowViewController:animated:
方法被发送到导航控制器的委托。 您需要将一个对象指定为该委托才能接收此消息。 然后,您将知道每次出现视图控制器。
阻塞主线程,不如使用 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:
中,以便知道您的 UI 已加载。这也意味着您不必依赖动画的时间。
我自己还没有测试或实现过,但文档听起来像:
navigationController:didShowViewController:animated:
描述为:在导航控制器显示视图控制器的视图和导航项属性后立即发送到接收器。
否则
setAnimationDidStopSelector:
可能是适合你的东西。
描述为:设置动画停止时要发送到动画委托的消息。