阅读 124

UITableView reloadData异步刷新问题

简介:

  UITableView的reloadData是异步的,在调用该方法后,会继续执行其它代码(tableView的布局、cell的显示和高度计算等代理方法,或者自己的一些代码等),不会阻塞主线程;即reloadDate并不会等待tableview更新结束后才返回,而是立即返回。这样就会导致无法确定reloadData后完成的时机,无法在reloadData完成后及时的做其它操作(例如滚动到指定单元格);如果表中的数据比较大或者布局比较复杂,在一个run loop周期没执行完,这时,需要对tableview视图数据的操作,就会出问题了(例如滚动到指定单元格)。
问题代码如下:

        self.tableView?.reloadData()
        self.tableView?.scrollToRow(at: IndexPath.init(row: self.selectedIndex, section: 0), at: .none, animated: true)

怎样解决这个问题呢,即怎么获取reloadData完成的时机呢?有三种方法,这三种方法的实现和原理如下:

方法一:reloadData后调用layoutIfNeeded

实现:

        self.tableView?.reloadData()
        self.tableView?.layoutIfNeeded()

  layoutIfNeeded会强制重绘,阻塞主线程,等待tableView的reloadData更新布局后,进行layoutIfNeeded的以后的代码,坏处是会阻塞主线程,造成不必要的卡顿。

方法二:reloadData后调用DispatchQueue.main.async方法

实现:

        self.tableView?.reloadData()
        DispatchQueue.main.async {
            self.tableView?.scrollToRow(at: IndexPath.init(row: self.selectedIndex, section: 0), at: .none, animated: true)
        }

  DispatchQueue.main.async等待主线程空闲时(在reloadData后,不在主线程做其它操作),即使tableView进行reloadData更新布局后调用,不会阻塞主线程,推荐使用该方法。

方法三:UIView.animate中调用reloadData,结束后再进行其它操作

实现:

        UIView.animate(withDuration: 0.25) {
            self.tableView?.reloadData()
        } completion: { (isFinish) in
            if isFinish {
                self.tableView?.scrollToRow(at: IndexPath.init(row: self.selectedIndex, section: 0), at: .none, animated: true)
            }
        }

  UIView.animate利用completion等待动画操作reloadData完成后调用。

作者:苍眸之宝宝

原文链接:https://www.jianshu.com/p/e6ba9321f8e9

文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐