iOS 在显示新视图之前 segue 冻结多秒

iOS segue freeze for many seconds before showing new view

在我的应用程序的主视图中,我有一个 table 视图和两个原型单元格。我已经使用故事板为每个单元格配置了转场。在视图控制器中,我重写了 prepareForSegue 以将有关所选单元格的信息传递到目标视图。

目标视图不是特别复杂,当然不需要任何繁重的处理来加载。

问题

当我第一次点击主控制器中的单元格时,目标视图会在 5 到 40 秒的长时间延迟后出现。

编辑 #2:后续点击通常更快

注意:

根据我对这个主题的阅读,我怀疑这个问题可能与后台线程中发生的上述某些操作有关。

知道我做错了什么吗?

编辑#1:添加了一些代码

在主视图控制器中,segues link 使用故事板(CTRL-将两个原型单元格拖到目标视图中)。

代码如下所示:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
    var assetIndex = assetsTable.indexPathForSelectedRow()?.row

    println("prepare for segue - start: \(assets[assetIds[assetIndex!]]!.Name)")

    if let destination = segue.destinationViewController as? AssetThingsListViewController
    {
        destination.bundlesRepository = bundlesRepository!
        destination.asset = assets[assetIds[assetIndex!]]
    }

    println("prepare for segue - end")
}

编辑 #3 我已经在 BitBucket

上提供了一个示例项目

很难说,除非您 post 您的代码响应单元格上的点击并呈现新的视图控制器。

UI 更改(或 UI 更改从未发生)长时间延迟的一个常见原因是试图从后台线程进行 UI 更改。您调用 segue 的代码是否可能在不同的线程上 运行?您可以通过在该代码上设置断点并观察中断时的线程号来轻松判断这一点。如果线程号为 0,则您在主线程上 运行。如果是其他线程号,那是你的问题。

我检查了你的项目。虽然我也找不到其他任何东西,但我也怀疑这是线程问题。

我设法通过为 tableview 实现委托并在代码中呈现新控制器来解决问题:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    let destination = storyboard?.instantiateViewControllerWithIdentifier("BuilderToysListViewController") as! BuilderToysListViewController
    destination.botsRepository = botsRepository!
    destination.builder = builders[builderIds[indexPath.row]]

    dispatch_async(dispatch_get_main_queue(), { () -> Void in
        self.presentViewController(destination, animated: true) { () -> Void in

        }
    })

}

请注意,您已设置视图控制器故事板 ID:BuilderToysListViewController 并且还设置了表视图委托。不要忘记删除 segues。

最后在新视图控制器中关闭视图使用此代码:

@IBAction func backButton(sender: AnyObject)
{
    dismissViewControllerAnimated(true, completion: { () -> Void in

    })
//        performSegueWithIdentifier("segueToysByBuilder", sender: nil)        

}

这将使您能够正确关闭视图,而不是错误地创建一个新视图。

同样值得将代码从 viewWillAppear 移动到 viewDidAppear

我能够通过实施以下内容解决 iOS 13 和 Swift 5 的问题:

DispatchQueue.main.async {
     self.performSegue(withIdentifier: "YOURSEGUEID", sender: nil)
}

里面
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {}

最终结果

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    DispatchQueue.main.async {
         self.performSegue(withIdentifier: "YOURSEGUEID", sender: nil)
    }
}