1.背景
在我公司的一个项目中,偶然发现使用MJRefresh时,在上滑加载更多数据后,再下滑查看上面内容时,列表出现了上下抖动的bug。(12秒左右能够看到)
<video id="video" controls="" preload="none" poster="">
<source id="mp4" src="https://blog-1257898483.cos.ap-chengdu.myqcloud.com/%E6%9C%AA%E5%91%BD%E5%90%8D.mov" type="video/mp4">
</video>
2.找寻出现问题的地方
在经过简单的测试之后,发现该bug在加载更多后下滑100%会复现,首先分析出现该问题出现的原因有以下几点:
- 滑动时tableView的contentOffset出现了异常变化
- 滑动时tableView的contentsize出现变化
接下来就需要验证到底是什么在滑动时出现了异常情况,我在didscorll代理方法中监听了scrollview的contentsize与contentoffset,发现在下滑时contentsize竟然发生了变化,首先我这个列表所有的Cell高度都是固定的,所以contentsize的变化让我有点想不通,还好经过万能的度娘提醒:
Self-Sizing在iOS11下是默认开启的,Headers, footers, and cells都默认开启Self-Sizing,所有estimated 高度默认值从iOS11之前的 0 改变为UITableViewAutomaticDimension
estimatedRowHeight这个属性是给tableView每行设置预估行高,如果目前项目中没有使用estimateRowHeight属性。
在iOS11的环境下就要注意了,因为开启Self-Sizing之后,tableView是使用estimateRowHeight属性的,这样就会造成contentSize和contentOffset值的变化,在估算行高机制下,contentSize的值是一点点地变化更新的,所有cell显示完后才是最终的contentSize值。因为不会缓存正确的行高,tableView reloadData的时候,会重新计算contentSize,就有可能会引起contentOffset的变化,就出现上述奇怪的现象。
3.解决问题
知道具体出现问题的地方后,接下来就是寻找解决方法,问题是由于tableview自动使用预估高度而产生的,所以我现在应该是只要给预估高度默认设置为0就能解决问题。
if #available(iOS 11.0, *) {
UITableView.appearance().estimatedRowHeight = 0
UITableView.appearance().estimatedSectionFooterHeight = 0
UITableView.appearance().estimatedSectionHeaderHeight = 0
}
全局设置一下预估高度,问题就解决了。但是我直接在控制器内设置tableview的estimatedRowHeight并没解决问题,这点我一直想不通,如果有大佬知道麻烦告知小弟,万分感谢。