在转到下一个视图控制器(Swift)之前进行异步调用

Posted

技术标签:

【中文标题】在转到下一个视图控制器(Swift)之前进行异步调用【英文标题】:Making an asynchronous call prior to a segue to the next view controller (Swift) 【发布时间】:2016-01-22 19:52:36 【问题描述】:

我有一堆视图控制器(嵌入式导航控制器),我需要在进入下一个屏幕之前进行一些异步调用。问题是我需要在单击映射到 segue 的按钮时进行此调用,但是由于尚未返回异步调用,因此进行了 segue 并显示了下一个视图控制器。人们如何做这种事情来防止在异步调用返回之前发生视图控制器导航?

【问题讨论】:

你有代码要显示吗? 不要,而是在新控制器中这样做 我不能在下一个控制器中这样做,因为只有在异步方法成功时才应该显示下一个视图控制器。 【参考方案1】:

TL;DR 您可以为 UIButton 创建一个 @IBAction,并在函数内部进行异步调用并在 completionHandler 中使用dispatch_async(dispatch_get_main_queue()) .

要手动创建你的 segue,只需 Ctrl+DragUIViewController 到下一个,如下图所示:

然后你会看到像这张图片一样选择segue的类型:

选择Show类型后,您可以在左侧视图的层次结构中看到segue,选择它来设置segue的标识符,如下图所示:

您可以使用函数performSegueWithIdentifier 手动启动segue 来解决您的问题,您可以在网上找到很多关于如何使用Interface Builder 手动创建segue 的教程。

创建 segue 后,您可以在任何地方调用它,在您的情况下,您将在异步调用的 completionHandler 中调用它,您需要使用Grand Central Dispatch 的dispatch_async(dispatch_get_main_queue()) 功能。

类似这样的代码:

 @IBAction func buttonTapped(sender: AnyObject) 
    asyncFunction() 
        dispatch_async(dispatch_get_main_queue()) 
            self.performSegueWithIdentifier("someID", sender: sender)
        
    

编辑: 请注意,在 Swift 3 中,语法发生了变化:

@IBAction func buttonTapped(_ sender: AnyObject) 
    asyncFunction() 
        DispatchQueue.main.async 
            self.performSegueWithIdentifier("someID", sender: sender)
        
    

希望对你有帮助。

【讨论】:

好吧,考虑到我通过 ctrl 从按钮拖动到下一个视图控制器在 IB 中创建了 segue,如何取消类似于“幕后”的 segue 操作?那还不被执行吗? 取消转场是什么意思? 好吧,如果我只是 ctrl 从按钮拖动到视图控制器,当我单击按钮时会发生 segue。这不会发生在我的代码中。建立连接时给定的(我选择的操作是“显示”)。 手动进行segue的方法不是Ctrl+Drag从UIButton到下一个ViewController,就像@dan说你需要在两个UIViewController之间做segue只是Ctrl +从第一个拖到第二个,从UIBUtton你需要的只是@IBAction Victor 的方法会奏效,只需注意向用户显示正在发生的事情,否则他们会一遍又一遍地点击按钮【参考方案2】:

听起来您正在寻找它同步运行;因此,如果您使用 GCD 调用 dispatch_sync 而不是 dispatch_async,则将繁重的工作放在后台线程上,并且当您需要 segue 发生时,通过调用 dispatch_sync(dispatch_get_main_queue(), ^ // handle error or segue 将事情放回主线程

【讨论】:

我可以拨打这个电话并显示等待计时器吗? 你可以在调度到后台线程之前显示一个等待计时器,并在事情回到主线程后删除它 @aduflo 你说的这不是处理问题的推荐方法,异步调用主要是为了避免 UI 冻结。 @VictorSigler 我认为他想根据此评论冻结 UI:How do people do this kind of thing to prevent view controller navigation happening before the async call is returned?

以上是关于在转到下一个视图控制器(Swift)之前进行异步调用的主要内容,如果未能解决你的问题,请参考以下文章

JavaFX 在转到下一个方法之前等待动画方法完成

使 angular.forEach 在转到下一个对象后等待承诺

如何使 segue 等待功能在按钮按下时完成?

Nextjs如何在转到下一页时不卸载上一页(保持状态)

使用 Facebook SDK 进行身份验证后转到下一个视图

将数据从一个视图控制器传递到下一个视图控制器,而无需在 swift 中进行 segue