首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >动画自定义UITableViewCell时的定时问题

动画自定义UITableViewCell时的定时问题
EN

Stack Overflow用户
提问于 2018-02-22 10:04:29
回答 2查看 333关注 0票数 1

我的应用架构有问题..。

我有一个UITableView,里面装满了定制的UITableViewCells。当然,我使用去队列,所以只生成8-10个单元实例。

继续解决我的问题..。我在我的应用程序中添加了一个主题特性。当用户长时间接触主UINavigationBar时,会在应用程序范围内发布通知,通知每个viewController更新他们的UI。

当使用自定义单元格承载tableView的tableView接收到通知时,它将调用tableView.reloadData()

这很好,因为我已经实现了func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)

willDisplay内部,我调用自定义tableViewCell上的一个方法,该方法使用UIViewAnimation对单元格进行适当的颜色更改。

看起来是这样的:

代码语言:javascript
复制
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    if let newsFeedItemCell = cell as? NewsFeedItemCell {
        if (self.nightModeEnabled) {
            newsFeedItemCell.transitionToNightMode()
        } else {
            newsFeedItemCell.transitionFromNightMode()
        }
    }
}

在自定义单元格实现中,这些方法如下所示:

代码语言:javascript
复制
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个单元格的引用,并检查它们是否脱离屏幕,是否立即设置状态。

但是,我不喜欢保留每个单元格的引用。

有什么想法吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-02-22 10:15:33

我不会使用reloadData来动画,因为您的表视图的数据模型实际上并没有改变。

相反,我会给UITableView一个函数,如下所示:

代码语言:javascript
复制
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中,在没有动画的情况下设置正确的外观。

票数 3
EN

Stack Overflow用户

发布于 2018-02-22 10:14:20

我会尝试以下几种方法。

没有使用UIView.animate,而是在transition(To/From)NightMode中创建一个执行相同动画的UIViewPropertyAnimator对象。我将保持对该对象的引用,然后准备重用,如果动画仍在运行,我只需完成该动画并重置状态。所以就像这样:

代码语言:javascript
复制
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()
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48924559

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档