最近开始做 iOS 的项目. 之前的 Android 开发经验导致有的时候总是有一些思维定势绕不过来(不认真看文档), 导致踩了一些不应该踩的坑.
1. UITableView 的 reloadData 的作用
刚开始看到 UITableView 的时候, 第一反应就是这货不就是一个 ListView. 所以看到 reloadData 这个函数的时候也没有细看文档, 就以为是 notifyDataSetChanged 一样的作用.
当数据变化比较大的时候, 比如删掉一个, 然后添加了10个之类的. 就直接 reload 了. 结果自然就造成了很多奇怪的现象, 让我都开始怀疑人生. 后来看到了文档, 文档里明确说不能在 beginUpdate 和 endUpdate 之间调用. 真是死的心的都有了.
文档的原文:
Call this method to reload all the data that is used to construct the table, including cells, section headers and footers, index arrays, and so on. For efficiency, the table view redisplays only those rows that are visible. It adjusts offsets if the table shrinks as a result of the reload. The table view’s delegate or data source calls this method when it wants the table view to completely reload its data. It should not be called in the methods that insert or delete rows, especially within an animation block implemented with calls to beginUpdates() and endUpdates().
2. 没有提供准确的 estimate height 导致 TableView 滚动状态出错
iOS 8 后 UITableView 提供了 Cell 的自适应机制. 方法也简单, 设置 estimatedHeight, 然后把 cellHeight 设成 UITableViewAutomaticDimension 即可.
在 Android 开发中自适应是一种天然的选择, 因为 Android 一开就面对各种奇怪尺寸的屏幕. 但是 iOS 设备一开始只有一种尺寸, 每一个设计图都可以精确到每一个 px. 所以自适应是后期引入的. 虽然没有具体考古过, 但是我想 UITableView 在设计支出一定也是没有考虑过自适应高度这一点.
即使在新的机制中, 我们依然要提供 estimatedHeight. 刚开始我以为这个只是一个随便给的值. 所以即使我的页面每一个 Cell 的高度都是不一样. 我依然随便提供了一个的数值.
后果当然很严重, 当我滚动 TableView 的时候就会出现一些奇怪的跳动. 有时候甚至会触发不停的来回滚动. 我的表情是这样的:
老老实实地滚回去看文档: Working with Self-Sizing Table View Cells. 里面提到:
Additionally, try to make the estimated row height as accurate as possible. The system calculates items such as the scroll bar heights based on these estimates. The more accurate the estimates, the more seamless the user experience becomes.
人与人的之间的信任都没有了. 不是说自适应!! accurate 和 estimated 对不上啊!!!
后续提供了比较精确的 estimated height. 滚动终于正常.