12

我希望这是一个简单的问题。如果我有一个 UINavigationController 并且我将一个新的视图控制器推送到带有动画转换的堆栈上,我如何检测动画何时完成并且新的视图控制器在屏幕上?

我有一些场景需要推送一个新控制器,然后必须执行长时间运行的操作。我想先推送新视图,以便在我开始长时间阻塞主线程之前屏幕上有一些东西。如果我在我的长时间运行的任务之后立即执行推送,则视图不会显示,直到两者都完成并且主线程能够再次处理事件之后。

所以,一旦动画完成并且视图在屏幕上,我想做的就是能够在新控制器中检测到,然后开始任务。

4

3 回答 3

23

+1 @Dhamrick 建议不要阻塞主线程。

要回答原始问题,您可以在两个地方检测 viewController 的变化:

  1. 你刚刚推送的 viewController 会收到viewWillAppear:viewDidAppear:消息。如果您想知道特定的 viewController 何时出现,请实现这些方法。

  2. navigationController:didShowViewController:animated:@Mike Z 提到的方法被发送到 navigationController 的delegate。您需要指定一个对象作为该委托方才能接收此消息。然后,您将知道每次viewController 出现。

于 2012-04-14T02:05:53.097 回答
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:以便您知道您的 UI 已经加载。这也意味着您不必依赖动画的时间。

于 2012-04-14T01:38:42.283 回答
3

我自己没有测试或实现过这个,但文档听起来像:

navigationController:didShowViewController:animated:

描述为:在导航控制器显示视图控制器的视图和导航项属性之后发送到接收器。

除此以外,

setAnimationDidStopSelector:可能对你有用。

描述为:设置动画停止时发送给动画代理的消息。

于 2012-04-14T01:32:31.927 回答