UITableView 的 reloadData() 的替代方案?
Alternative for UITableView's reloadData()?
我的 table 视图的可重用单元格中有一个 UISlider
。
一旦值发生变化,就会调用自定义方法 valueChanged()
,这会触发table 视图的 reloadData()
方法。
reloadData()
调用 cellForRowAtIndexPath
并且一旦更改了滑块的单元格被加载,它就会激活两个约束,这应该使它看起来好像一个按钮从单元格的右侧滑入。
基本上,我试图创建的效果是,一旦用户开始滑动 UISlider
,动画就会发生,按钮就会出现。
但问题是:UISlider
的 isContinious
属性 设置为 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
}
我的 table 视图的可重用单元格中有一个 UISlider
。
一旦值发生变化,就会调用自定义方法 valueChanged()
,这会触发table 视图的 reloadData()
方法。
reloadData()
调用 cellForRowAtIndexPath
并且一旦更改了滑块的单元格被加载,它就会激活两个约束,这应该使它看起来好像一个按钮从单元格的右侧滑入。
基本上,我试图创建的效果是,一旦用户开始滑动 UISlider
,动画就会发生,按钮就会出现。
但问题是:UISlider
的 isContinious
属性 设置为 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
}