最新编辑: 经过一些更多的实验,我确信我遇到了触摸处理问题 我创建了一个自定义单元格,其子视图填充了内容视图宽度的一半。我正在为该子视图设置动画而不是内容视图。
在触摸单元格右侧的同时滚动桌面视图可正常工作 滚动单元格左侧的表格视图(动画视图所在的位置)会导致滞后。
修改 最后,我尝试做类似to this one的动画。 该问题中接受的答案与我提出的问题相同。 下面的代码是最简单的代码,可以重现这个问题。
在dequeCellForIndexPath
而不是willDisplayCell
中制作动画没有任何区别。
在willDisplayCell
中进行动画制作时,表格视图滚动动画会变慢。当您尝试在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行
没有动画我到达第400行
在willDisplayCell中随机延迟0到0.3秒之间,阻止主队列,我到达第120行
我想某处的触控处理存在问题。
即使the library I use to visualize how fast I'm scrolling,在willDisplayCell
中使用动画时也会中断。
答案 0 :(得分:2)
尝试在tableView.dequeueReusableCellWithIdentifier(..)
功能中使用cellForRowAtIndexPath
。我尝试了下面的代码,滚动性能看起来很好。我还添加了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()
}
答案 1 :(得分:1)
所以,你当然应该将细胞出列而不是一直重新创建细胞。在您的测试中,不会产生太多差异,但随着您的细胞变得越来越复杂,它将会发挥作用。
此外,您需要考虑何时使用动画,以及动画应该有多大。有一个原因是集合视图上的股票动画仅适用于要添加的项目 - 因为它是动画的有效使用。通常,当用户向上滚动时,这些项目不是新的,因此单元格中滚动到视图中的任何动画都是一个令人困惑的范例。
现在,当向下滚动时,我可以看到为什么你可能想要动画。在这种情况下你需要考虑滚动速度 - 如果你滚动然后动画很难/不可能看到,所以没有意义这样做......
因此,跟踪滚动速度。在简单的选项中,如果您滚动速度超过某个阈值速度,那么就不要进行动画处理。在复杂选项中调整动画的大小以获得滚动速度,因此慢速滚动仍然具有大部分动画,并且动画中的滚动速度更快,直到达到该阈值并且关闭所有动画。
答案 2 :(得分:0)
正如其他人所说,首先你必须将一个单元格出列而不是每次都初始化一个单元格。
如果您使用AutoLayout
进行细胞布局,我建议将其删除如果没有其他工作。 (这是一个很棒的功能,但它也需要很多CPU时间。)
但我的解决方案是解决方法,不要使用UIViewAnimation
。请改用UIScrollViewDelegate
。在scrollViewDidScroll
方法中,获取tableView
的可见单元格并设置最后一个单元格的alpha,方法是直接计算它与屏幕底部的距离,而不需要任何动画。