Ios 如何检测UINavigationController动画何时完成?

Ios 如何检测UINavigationController动画何时完成?,ios,iphone,objective-c,uikit,Ios,Iphone,Objective C,Uikit,我希望这是一个简单的问题。如果我有一个UINavigationController,并且我使用动画转换将一个新的视图控制器推到堆栈上,那么我如何检测动画何时完成以及新的视图控制器何时出现在屏幕上 我有几个场景需要推送一个新的控制器,然后它必须执行长时间运行的操作。我想先推新视图,这样在我长时间阻塞主线程之前,屏幕上会出现一些东西。如果我在长时间运行的任务之后立即执行推送,那么视图将不会显示,当然,直到这两个任务都完成并且主线程能够再次处理事件之后 所以,我想做的是,一旦动画完成,视图出现在屏幕上

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

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


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

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

navigationController:didShowViewController:animated:

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

否则,

setAnimationDidStopSelector:
可能适合您


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

不要阻塞主线程,而应该使用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已经加载了。这也意味着您不必依赖于动画的计时。

+1到@DHamrick的建议,完全不阻塞主线程

要回答原始问题,可以在两个位置检测viewController更改:

  • 刚才按下的viewController将接收和消息。如果您想知道特定的viewController何时出现,请实现以下方法

  • @Mike Z提到的
    navigationController:didShowViewController:animated:
    方法被发送到navigationController的。您需要将一个对象分配给该委托才能接收此消息。然后,您将知道每次出现viewController时


  • 另一方面,为什么
    dispatch\u get\u global\u queue()
    而不是
    dispatch\u queue\u create()
    ?我一直使用后者,但现在回想起来,只有少数情况下我需要严格的串行队列,但我想我可以转向并发队列。除了显而易见的(例如,在需要时使用串行)之外,是否考虑了串行队列与并发队列?我通常在希望保证对给定资源的单一访问时创建一个队列。例如,如果我有一个数据库连接,我想保证它不会被并发访问。是的,我使用一个队列的原因与此完全相同,我将保留这个队列(这是我对“我需要严格串行队列的地方”的引用)。但是我想我已经养成了总是创建自己的队列的习惯,但是你让我意识到这不是必要的(而且可能不是对系统资源的良好利用)。我将开始使用
    dispatch\u get\u global\u queue()
    更多信息。谢谢你的洞察力。(顺便说一句,这就是我喜欢的地方。)我试着编辑这篇文章,但是我的编辑太短了。请注意,这应该是dispatch_get_global_queue(dispatch_queue_PRIORITY_BACKGROUND,0);,在此处传递NULL会导致警告。视图控制器上出现的ViewDid似乎就是我想要的。我不能在单独的线程上完成这项工作,因为正在执行的代码不是线程安全的。谢谢你的建议。谢谢你,你的回答帮助了我