「这是我参与11月更文挑战的第19天,活动详情查看:2021最后一次更文挑战」
前言
在tableview的使用过程中, 常常有这样一种业务就是在tableview的下面再增加一些业务模块什么的, 那么就要求我们拿到tableview的具体高度, 然后在后续的业务才能安排的文档, 不然就会出现叠加等不正常的情况发生.
但是这里又有一个问题, 那就是tableview的高度是变化的, 而不是确定的, 经常会超出屏幕的很多倍, 并且tableview中的cell的高度也是动态变化的, 所以tableView的高度并不是可以提前就获取到的.
如果是通过tableview的frame获取,那么获取到的frame并不是实际上的高度.
如果是通过tableView的contentSize获取的话, 由于reloadData不是同步执行的, contentSize也是延后的,所以也是获取不是实际上的告诉
那么如何获取tableView的实际高度呢?
实现
通过重绘视图的方式来让reloadData执行完毕之后, 再获取tableView的contentSize,这样就会是准确的了, 但是有一个坏处就是, 如果tableView上的cell控件比较复杂,数据过多等情况的话, layoutIfNeeded会导致主线程阻塞, 给用造成卡顿的体验,非常不好
self.view.layoutIfNeeded()
let height = self.tableView.contentSize.size.height
还有一种比较不常规的办法来实现, 那么就是将获取tableView的contentSize延后0.1秒后再执行, 让tableView有时间来重绘完成视图, 但是这样也有一个问题, 就是无法准确的时候contentSize是什么时间完成的, 有可能提前, 也有可能延后, 这是一个不建议的方案
DispatchQueue.main.asyncAfter
如果项目中cell是固定的行高, 不涉及动态高度的话, 那么可以通过设置estimatedRowHeight属性等于0, 来实现, 那么就可以通过直接获取contentSize来获取高度.
当然如果cell高度是固定的话, 直接通过数据的数量 * cell的高度, 来直接获取tableView的高度, 只不过是需要通过一些计算才能获取的