iOS:在 willDisplayCell 中执行动画时 UITableView 加速变慢

标签 ios swift uitableview uikit core-animation

最新编辑: 经过更多实验后,我确信我遇到了触摸处理问题。
我创建了一个带有 subview 的自定义单元格,该 subview 填充了内容 View 宽度的一半。我正在为该 subview 而不是内容 View 设置动画。

Cell with Half view

在触摸单元格右侧的同时滚动表格 View 可以正常工作。
滚动单元格左侧的表格 View (动画 View 所在的位置)会导致延迟。

编辑: 最后,我正在尝试制作类似 to this one 的动画. 该问题中接受的答案与我要问的问题相同。 下面的代码是重现该问题的最简单的代码。

dequeCellForIndexPath 而不是 willDisplayCell 中执行动画没有任何区别。

willDisplayCell 中做动画时,表格 View 滚动动画变慢。当您尝试在 tableview 中快速滚动时,滚动会失去加速度。

一些重现问题的示例代码:

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

    @IBOutlet var tableView: UITableView!

    func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {

        cell.contentView.layer.opacity = 0.0

        UIView.animateWithDuration(0.3) {
            cell.contentView.layer.opacity = 1.0
        }
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = UITableViewCell()

        cell.textLabel?.text = "\(indexPath.row)"

        return cell
    }


    func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        return 300
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 5000
    }
}

当单元格的高度很大时,问题会变得更糟。

有没有办法避免这种情况,或者有更好的函数来制作单元格动画?

相关:Blogpost on doing animations like this

编辑 2: 说明问题的 GIF:

在所有 3 种情况下,我都在手机上尽可能快地滚动。

通过 willDisplayCell 中的动画,我到达了第 60 行

Using Animation

没有动画我到达了 400+ 行

Normal Scrolling

在 willDisplayCell 中随机延迟 0 - 0.3 秒,阻塞主队列,我到达第 120 行

Laggy Scrolling

我猜某处的触摸处理有问题。

甚至the library I use to visualize how fast I'm scrolling , 在 willDisplayCell 中使用动画时中断。

最佳答案

尝试在 cellForRowAtIndexPath 函数中使用 tableView.dequeueReusableCellWithIdentifier(..)。我尝试了下面的代码,滚动性能对我来说很好。我还添加了 cell.contentView.layer.removeAllAnimations() 以在单元格消失后取消动画。

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    guard let cell = tableView.dequeueReusableCellWithIdentifier(identifier) as? TableViewCell else { fatalError("where's my cell") }
    cell.textLabel?.text = "\(indexPath.row)"
    return cell
}

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return 300
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 5000
}

override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    cell.contentView.layer.opacity = 0.0
    UIView.animateWithDuration(0.3) {
        cell.contentView.layer.opacity = 1.0
    }
}

override func tableView(tableView: UITableView, didEndDisplayingCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    cell.contentView.layer.removeAllAnimations()
}

关于iOS:在 willDisplayCell 中执行动画时 UITableView 加速变慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39397707/

相关文章:

ios - 有没有更有效的方法来检测 UIScrollView 偏移量?

ios - Swift:在与 View 匹配的tapGestureRecognizer中播放声音

xcode - 视差滚动 SpriteKit

iOS tableView 分页

ios - 带有选择器 View 的弹出窗口未正确显示

ios - 在 Swift 中从 Firebase 构建和检索数据的问题

swift - "CGFloat is not convertible to Int"尝试计算表达式时

ios - 如何在 swift 中将字节数组转换为 base64 字符串?

ios - 在 iOS 的 UItableview 中将行推到顶部

ios - 访问 tableView 内的 UIBarBarItem 按钮 didSelectRowAtIndexPath swift