我的应用架构有问题..。
我有一个UITableView,里面装满了定制的UITableViewCells。当然,我使用去队列,所以只生成8-10个单元实例。
继续解决我的问题..。我在我的应用程序中添加了一个主题特性。当用户长时间接触主UINavigationBar时,会在应用程序范围内发布通知,通知每个viewController更新他们的UI。
当使用自定义单元格承载tableView的tableView接收到通知时,它将调用tableView.reloadData()
这很好,因为我已经实现了func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
在willDisplay内部,我调用自定义tableViewCell上的一个方法,该方法使用UIViewAnimation对单元格进行适当的颜色更改。
看起来是这样的:
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if let newsFeedItemCell = cell as? NewsFeedItemCell {
if (self.nightModeEnabled) {
newsFeedItemCell.transitionToNightMode()
} else {
newsFeedItemCell.transitionFromNightMode()
}
}
}在自定义单元格实现中,这些方法如下所示:
func transitionToNightMode() {
UIView.animate(withDuration: 1, animations: {
self.backgroundColor = UIColor.black
self.titleTextView.backgroundColor = UIColor.black
self.titleTextView.textColor = UIColor.white
})
}
func transitionFromNightMode() {
UIView.animate(withDuration: 1, animations: {
self.backgroundColor = UIColor.white
self.titleTextView.backgroundColor = UIColor.white
self.titleTextView.textColor = UIColor.black
})
}这个很好..。以下是问题所在:
在滚动tableView时,任何不在屏幕上的单元格都有它们的颜色更新/动画代码,因为它们滚动到屏幕上,这会导致用户的不愉快体验。
当然,我理解为什么会发生这种情况,因为willDisplay只被称为单元格显示。
我想不出一种优雅的方法来避免这种情况。
我很高兴在屏幕上的是动画的用户体验是愉快的,然而,对于细胞离开屏幕,我宁愿他们跳过动画。
可能的解决方案(虽然不优雅):
保持对cellForRow创建的8-10个单元格的引用,并检查它们是否脱离屏幕,是否立即设置状态。
但是,我不喜欢保留每个单元格的引用。
有什么想法吗?
发布于 2018-02-22 10:15:33
我不会使用reloadData来动画,因为您的表视图的数据模型实际上并没有改变。
相反,我会给UITableView一个函数,如下所示:
class myClass : UITableViewController {
....
func transitionToNightMode() {
for visible in visibleCells {
UIView.animate(withDuration: 1, animations: {
visible.backgroundColor = UIColor.black
visible.titleTextView.backgroundColor = UIColor.black
visible.titleTextView.textColor = UIColor.white
})
}
}
}然后在您的willDisplay或cellForItemAt中,在没有动画的情况下设置正确的外观。
发布于 2018-02-22 10:14:20
我会尝试以下几种方法。
没有使用UIView.animate,而是在transition(To/From)NightMode中创建一个执行相同动画的UIViewPropertyAnimator对象。我将保持对该对象的引用,然后准备重用,如果动画仍在运行,我只需完成该动画并重置状态。所以就像这样:
fileprivate var transitionAnimator: UIViewPropertyAnimator?
fileprivate func finishAnimatorAnimation() {
// if there is a transitionAnimator, immediately finishes it
if let animator = transitionAnimator {
animator.stopAnimation(false)
animator.finishAnimation(at: .end)
transitionAnimator = nil
}
}
override func prepareForReuse() {
super.prepareForReuse()
finishAnimatorAnimation()
}
func transitionToNightMode() {
transitionAnimator = UIViewPropertyAnimator(duration: 1, curve: .easeInOut, animations: {
self.backgroundColor = UIColor.black
self.titleTextView.backgroundColor = UIColor.black
self.titleTextView.textColor = UIColor.white
})
transitionAnimator?.startAnimation()
}
func transitionFromNightMode() {
transitionAnimator = UIViewPropertyAnimator(duration: 1, curve: .easeInOut, animations: {
self.backgroundColor = UIColor.white
self.titleTextView.backgroundColor = UIColor.white
self.titleTextView.textColor = UIColor.black
})
transitionAnimator?.startAnimation()
}https://stackoverflow.com/questions/48924559
复制相似问题