在 didSelectRowAtIndexPath 中呈现缓慢的 ViewController

Posted

技术标签:

【中文标题】在 didSelectRowAtIndexPath 中呈现缓慢的 ViewController【英文标题】:ViewController presented slowly in didSelectRowAtIndexPath 【发布时间】:2015-07-31 03:36:03 【问题描述】:

我想在didSelectRowAtIndexPath 上显示下一个 ViewController,并且发生如下。

  func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
        var section = indexPath.section
        var row = indexPath.row
        var cell:UITableViewCell = self.tblView.dequeueReusableCellWithIdentifier("cell") as! UITableViewCell
      cell.textLabel?.text = "hello"
       return cell
   

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

        let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
        frequentVC = storyboard.instantiateViewControllerWithIdentifier("frequentVC") as? DropOffFrequentVC
        self.presentViewController(frequentVC!, animated: true,completion: nil)
    

nextViewController 出现,我将 UIViewController 解散为 self.dismissViewControllerAnimated(true, completion:nil) 并再次调用以前的 UIViewController 但现在当我等待一段时间并再次尝试呈现 UIViewController 时,UIViewController 的调用速度非常慢但是didSelectRowAtIndexPath 会立即被调用。在等待期间,如果我在任何地方点击 aroundView,则会立即呈现UIViewController。此外,如果我点击两次UIViewController,则会立即呈现。

项目如下: https://drive.google.com/open?id=0B6dTvD1JbkgBN0J3SkFOTDJtZlU&authuser=0

【问题讨论】:

viewDidLoad中初始化viewcontroller并将其存储为实例变量是否有帮助? 不......还是一样...... 我已经上传了项目...请看一下 【参考方案1】:

我遇到过很多次了。

我不完全明白为什么这可以解决问题,但它确实有效。

tableView.deselectRow(at: indexPath, animated: false)

确保animated 为假,并在呈现视图控制器之前调用它。

我的假设:

选定的单元格是第一响应者。 因此它负责展示新的视图控制器。 因此滞后。 我们看不到实际的UITableViewCell 代码,因为它是私有的,但其中的某些东西负责延迟执行该操作。

注意:上面的回复说延迟是由于使用了故事板。 这是错误的,因为我没有使用情节提要,而且我仍然有滞后。

【讨论】:

非常感谢!那行得通。我也使用纯代码,没有故事板等。有趣的是,如果我执行以下任一操作,我没有看到滞后:1/在导航控制器上推送 VC(而不是模态显示)2/从 UICollectionView 呈现而不是一个 UITableView。所以,我认为很明显 UITableView 中存在一些错误。我很惊讶其他人没有经常遇到这种情况。【参考方案2】:

我下载了你的代码。在打开ViewController 时没有遇到任何延迟。这可能取决于您计算机上的性能(如果像我一样在模拟器中运行)。

但是,您绝对应该对代码进行一些更改。首先研究如何构建故事板。您现在在代码中制作了很多 UI,这既困难又在您的情况下性能不好。每次调用 cellForRowAtIndexPath 时总是创建一个新的 UILabel 和其他 UI 元素是一种不好的做法。

其次,将seques 与情节提要一起使用也会让您的生活更轻松。跳过presentViewController,改用performSegueWithIdentifier等方法。只需在视图之间拖动即可直接在界面生成器中创建许多逻辑。

http://www.raywenderlich.com/81879/storyboards-tutorial-swift-part-1

【讨论】:

感谢您的建议....但问题是首先您选择一个单元格...然后关闭 ViewController,然后等待大约 10 秒钟,然后再次点击相同的单元格,您将获得非常慢..或者你可能需要点击两次才能呈现另一个视图控制器......我已经在真实设备中测试过它并且也有同样的问题 有趣的部分是你越等慢视图控制器出现 我猜它与内存有关。测试以在 Profiler 中运行它。 怎么可能......我现在在调试时减少了非常简化的代码......只包含一个表格视图...... 仍然可以正常工作。内存和CPU似乎还不错。如果在关闭后单击一行有时会有点滞后,但这可能与 let storyboard = UIStoryboard(name: "DropOff", bundle: nil)instantiateViewControllerWithIdentifier 创建可能需要时间的新对象有关。考虑将此代码放在viewDidLoad 中或尝试使用专门为此构建的segue。我也只会使用一个故事板。【参考方案3】:

你应该在主线程中显示你的视图控制器,就像:

DispatchQueue.main.async 
    self.presentViewController(
        frequentVC!, 
        animated: true,
        completion: nil
    )

【讨论】:

以上是关于在 didSelectRowAtIndexPath 中呈现缓慢的 ViewController的主要内容,如果未能解决你的问题,请参考以下文章

tableView - didSelectRowAtIndexPath 未调用

在 didSelectRowAtIndexPath 中呈现缓慢的 ViewController

我可以麻烦UITableViewDelegate的didSelectRowAtIndexPath:吗?

在 didselectRowAtIndexPath 之后 UITableView 无法滚动底部

在 tableView 上使用 CustomCell,如何调用 didSelectRowAtIndexPath?

didSelectRowAtIndexPath 不会在 ViewController 中触发