UITableView 的 reloadData() 的替代方案?

Alternative for UITableView's reloadData()?

我的 table 视图的可重用单元格中有一个 UISlider
一旦值发生变化,就会调用自定义方法 valueChanged(),这会触发table 视图的 reloadData() 方法。 reloadData() 调用 cellForRowAtIndexPath 并且一旦更改了滑块的单元格被加载,它就会激活两个约束,这应该使它看起来好像一个按钮从单元格的右侧滑入。

基本上,我试图创建的效果是,一旦用户开始滑动 UISlider,动画就会发生,按钮就会出现。
但问题是:UISliderisContinious 属性 设置为 true 以确保动画立即发生,并且不会延迟直到用户将手指放在滑块上。然而,将 isContinious 设置为 true 会使 reloadData()(在我的自定义 valueChanged() 中)在用户提交的每张小幻灯片中被调用很多次。

在做了一些研究并尝试了很多调试策略之后,我现在知道一旦 reloadData() 被调用,任何 运行 动画(仍然是动画在 reloadData() 被调用时)被打断并在动画完成后移动到它应该处于的状态。

所以回顾一下场景:

1) 滑块移动,
2) valueChanged()触发reloadData(),
3) 动画开始更新布局,
4) reloadData() 立即再次调用破坏了在步骤 3 中启动的动画。

isContinious 设置为 true 时,一切都发生得如此之快,因此在再次调用 reloadData() 之前动画没有获得完成所需的时间。这会破坏动画并使其看起来好像按钮只是出现在没有动画的屏幕上,即使我知道 UIView.animate(withDuration:) 确实被调用并正常工作。我想知道是否有一种方法可以在不调用 reloadData() 的情况下刷新 table,因此基本上可以替代此方法(我已经尝试过 reloadCellAtIndexPath,并且效果完全相同)。如果没有,有没有办法绝对确保动画完成而不会被任何其他布局更新方法打断?

如果问题是刷新杀死了动画,您可以推迟 reloadRowsAtIndexPaths 调用,直到动画完成执行。通常我会说在你的动画块的完成处理程序中调用它,但看起来你的值改变可能会触发多个动画。相反,当您启动动画时,还会启动一个计时器,该计时器将 运行 一个块来执行重新加载。如果你开始一个新的动画,让旧的计时器失效并制作一个新的。重新加载只会在最终动画完成时执行。

    var timer = Timer()

    func valueChanged() {
        timer.invalidate()
        timer = Timer.scheduledTimer(withTimeInterval: animationDuration, repeats: false) { _ in
            //Call reload here
        }
        //Animate here
    }