UITableView 的 reloadData() 的替代方案?
Posted
技术标签:
【中文标题】UITableView 的 reloadData() 的替代方案?【英文标题】:Alternative for UITableView's reloadData()? 【发布时间】:2016-10-27 06:09:34 【问题描述】:我的表格视图的可重用单元格中有一个UISlider
。 只要值发生变化,就会调用自定义方法valueChanged()
,它会触发表格视图的reloadData()
方法。
reloadData()
调用 cellForRowAtIndexPath
并且一旦加载了更改滑块的单元格,它就会为两个约束设置动画,这应该使它看起来好像一个按钮从单元格的右侧滑入。
基本上,我想要创建的效果是,一旦用户开始滑动UISlider
,动画就会发生并出现按钮。 不过,这里有一个问题:UISlider
的isContinious
属性设置为true
以确保动画立即发生,并且在用户将手指移到滑块之前不会延迟。但是,将isContinious
设置为true
使得reloadData()
(在我的自定义valueChanged()
中)在用户提交的每一张小幻灯片中都会被调用很多次。研究,并尝试了很多调试策略,我现在知道,一旦调用 reloadData()
,任何正在运行的动画(在调用 reloadData()
时仍在动画中)都会被打断并进入它的状态应该在动画完成后进入。
所以回顾一下这个场景:
1) 滑块移动, 2) valueChanged()
触发 reloadData()
, 3) 动画开始更新布局, 4) reloadData()
立即被再次调用,破坏了开始的动画第三步。
当isContinious
设置为true
时,一切都发生得如此之快,因此动画在reloadData()
再次被调用之前没有得到完成所需的时间。这会破坏动画并使它看起来好像按钮只是出现在屏幕上而没有动画,即使我知道UIView.animate(withDuration:)
确实被调用并正常工作。我想知道是否有一种方法可以在不调用reloadData()
的情况下刷新表格,所以基本上可以替代这种方法(我已经尝试过reloadCellAtIndexPath
,效果完全相同)。如果没有,有没有办法绝对确保动画完成而不会被任何其他布局更新方法中断?
【问题讨论】:
【参考方案1】:如果问题是刷新杀死了动画,您可以推迟 reloadRowsAtIndexPaths 调用,直到动画完成执行。通常我会说在你的动画块的完成处理程序中调用它,但看起来你的值改变可能会触发多个动画。相反,当您启动动画时,还会启动一个计时器,该计时器将运行一个块来执行重新加载。如果您开始一个新动画,请使旧计时器无效并制作一个新计时器。重新加载只会在最终动画完成后执行。
var timer = Timer()
func valueChanged()
timer.invalidate()
timer = Timer.scheduledTimer(withTimeInterval: animationDuration, repeats: false) _ in
//Call reload here
//Animate here
【讨论】:
谢谢!我最终没有使用计时器,但是您的想法是从动画块触发计时器让我想到只使用自定义布尔值来检查动画是否仍在运行。我不知道 UIView 的 animateWithDuration 的完成块是在动画完成后调用的。我一直认为它是在动画开始后立即调用的,并且完成块内的布尔参数指示动画是否仍在运行。 在我弄清楚这一点之后,创建我自己的 isAnimating 布尔值只是一件简单的事情,它在动画开始时设置为 true,在完成块中设置为 false,在动画之后完毕。在我的 valueChanged 方法(每秒被调用无数次)中,我只检查 isAnimating 是否设置为 false,如果是,则只运行 reloadData() 代码。奇迹般有效。所以基本上,因为我误解了 animateWithDuration 的完成块的目的,我使这个问题比原来要复杂得多。以上是关于UITableView 的 reloadData() 的替代方案?的主要内容,如果未能解决你的问题,请参考以下文章
UITableView.reloadData() 没有刷新 tableView。没有错误信息
UITableView 的 reloadData() 的替代方案?
UITableView 强制 sectionIndex 更新而不调用 reloadData
调用 reloadData 时 UITableView 有不需要的动画