文档章节

IOS 列表行高的自动计算 解决开发中痛点

人独立
 人独立
发布于 2015/10/13 11:54
字数 1375
阅读 2486
收藏 20

UITableView一直是我们app中使用频率最高的控件。UITableViewCell的算高问题也一直是一个老生常谈的问题。我们一般算高都是将cell中得各个控件的高度计算出来,然后给外界抛出一个接口,用来获取cell高度。如果cell是定高还好,如果是变高,我们还要计算文字图片的高度,每一个不同的cell 都有一大段算高的代码,而且tableview返回高度的代理方法,总是很频繁的调用,我们还要注意不要在主线程使用过于复杂的算法以免阻塞主线程。有时候,这些事情会搞得我们不胜其烦,我们总是把焦点放在这些地方,它耗费了我们大量的时间,我们急需要一种解决方案,可以将我们从其中解脱出来。

1.预加载

苹果已经注意到了这个问题,所以它在IOS7新增加了一个API

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(7_0);

有人对这个方法有印象吗?这是IOS7之后新添加的方法。解释这个方法之前,需要先了解tableView的算高机制。

我们以前通常使用heightForRowAtIndexPath方法返回对应cell高度,tableView在渲染之前都要调用这个方法来获取各个cell的高度,然后得到tableView的总高度,这意味在显示tableView之前需要进行大量的高度计算。注意这不是一屏,是计算所有数据的高度,并且是在主线程,很有可能会造成加载过慢,卡顿等现象。有人问为什么不能等页面滑动到某个 cell 的时候,再计算高度呢?答案就是,tableView有一个小的ScrollIndicator滚动条,高度是用来确定滚动条的大小和位置的。

estimatedHeightForRowAtIndexPath这个方法的意思就是返回一个cell 高度的估计值,这样tableView就直接取估值用来确定滚动条的信息而不需要调用多次算高的代理方法,这样就可以大幅度提高tableView的加载速度。

需要注意的是:1.它是IOS7之后才有的API。2.如果你的业务需求需要你一开始使用到tableView的contentSize或者contentOffset,那么请慎用。

2.autoLayout自动算高

现在有一种方案可以让我们不用费劲脑力去计算令人厌烦的行高,就是从autoLayout上面获取我们想要的cell高度。

在IOS8 WWDC上面苹果提出了一个概念self-sizing cell ,可以让cell根据内容自我适应高度。开启的方法就是开启上面提到的估算高度。

tableView.estimatedRowHeight = 44;


这样一句话就可以了。

为什么开启估算行高才能使用self-sizing?我猜可能是用autoLayout计算行高,会耗费大量的CPU时间,不开启估算行高,可能开始会一下子把主线程卡住,这样体验非常的不好。而且IOS8的tableView的滚动机制与以往不同,它没有做行高缓存,当你滚动的时候,它会频繁调用计算行高的代理方法。

可惜苹果的节奏总是慢那么一拍,我们在IOS7及更早的版本就无法使用self-sizing。但是一般的app都要求适配IOS7或者更早的版本,这样就需要我们自己去处理一下我们首先要用cell的contentView调用systemLayoutSizeFittingSize:方法计算出cell所需的高度是多少。使用UILayoutFittingCompressedSize参数可以得到适合cell中所有内容所需的最小尺寸。然后其高度就可以作tableView:heightForRowAtIndexPath:方法的返回值。

在当我准备写一套autoLayout自动算高的扩展时,我发现了有人为我们写好了它,于是我决定不再重复造轮子了。

UITableView+FDTemplateLayoutCell

为我们提供了一个自动计算行高,并且运行流畅(可以缓存行高),而且最低支持IOS6的一站式解决方案。具体的原理大家可以看它的源码。我在这里说一下大致的使用方法。

1.首先你的layout需要设置正确。在UITableViewCell子类中,添加布局约束,使得cell子视图的边缘固定(pin)到cell的contentView的边缘(最重要的是要有顶部和底部的边距约束条件)。注意:不要将子视图的边距约束固定到cell本身上了,只能固定到cell的contentView上, 确保每个子视图垂直方向上的内容压缩阻力(compression resistance)和吸附性约束(hugging constraints)没有被你添加的更高优先级的约束条件覆盖,让这些子视图的固有内容尺寸(intrinsic content size)来驱动contentView的高度。(看不懂推荐这本书 《iOS Auto Layout开发秘籍》)

2.在tableView中注册你的cell

[tableView registerNib:[UINib nibWithNibName:@"Cell" bundle:nil]  forCellReuseIdentifier:@“Cell"];
或者
[tableView registerClass:[Cell class] forCellReuseIdentifier:@“Cell”];

3.改写tableView的高度代理方法,代码如下

#import <UITableView+FDTemplateLayoutCell.h>
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return [tableView fd_heightForCellWithIdentifier:@"identifer" cacheByIndexPath:indexPath configuration:^(id cell) {
        // 配置 cell 的数据源,和 "cellForRow" 干的事一致,比如:
        cell.entity = self.feedEntities[indexPath.row];
    }];
   }

github 请戳我

enjoy it 

© 著作权归作者所有

人独立
粉丝 5
博文 39
码字总数 17213
作品 0
昌平
程序员
私信 提问
使用 Interface Builder 兼容 iOS6 和iOS7

当你在更新你的App到iOS 7的平台时遇到最大的挑战之一就是确保不要遗忘那些还在使用iOS 6平台的用户,在此我们提供一些建议使你的App应用在iOS 6和iOS 7上同时保留视觉吸引力和技术功能. 此图...

isaced
2014/01/15
13.4K
12
Facebook iOS 新版开发手记:两倍速度的背后

Facebook上周发布了新版iOS应用,号称速度提升两倍。Facebook工程师Jonathan Dan在Facebook官方页面中撰文,介绍了新版iOS应用、Facebook iOS应用的发展历程以及开发思路。《创事记》特选取此...

oschina
2012/08/30
2.7K
13
hbuilder + MUI 编写跨平台移动端app目前发现的优缺点

MUI这套UI框架,对于我这种CSS菜鸟来说,读懂里面的代码确实很难,而且怎么说框架中也存在的一些大坑,我这样的小白,要花上一段时间去学习。相对于react-native 这点的话还是facebook做的好...

Chendj
2015/10/26
8.6K
2
在iOS中运用React Component的思路,效率更高的开发UI,更好的复用UI组件

最近一直在看React的一些东西,其实很早前就想开始重拾前端,但是一直提不起兴趣再去看JavaScript,对CSS这种布局方式也不是很来感,说白了,就是懒吧😂。去年年底开始在公司app里开始尝试...

Kobe_Dai
04/03
0
0
面试官自述:面向高级开发人员的iOS面试问题

当您准备进行技术性iOS面试时,了解您可能会询问哪些主题以及经验丰富的iOS开发人员期望什么是非常重要的。 这是许多硅谷公司用来衡量iOS候选人资历水平的一系列问题。 这些问题涉及iOS开发的...

菇哒微课
2018/04/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周六乱弹 —— 早上儿子问我他是怎么来的

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @凉小生 :#今日歌曲推荐# 少点戾气,愿你和这个世界温柔以待。中岛美嘉的单曲《僕が死のうと思ったのは (曾经我也想过一了百了)》 《僕が死の...

小小编辑
今天
2.1K
14
Excption与Error包结构,OOM 你遇到过哪些情况,SOF 你遇到过哪些情况

Throwable 是 Java 中所有错误与异常的超类,Throwable 包含两个子类,Error 与 Exception 。用于指示发生了异常情况。 Java 抛出的 Throwable 可以分成三种类型。 被检查异常(checked Exc...

Garphy
今天
38
0
计算机实现原理专题--二进制减法器(二)

在计算机实现原理专题--二进制减法器(一)中说明了基本原理,现准备说明如何来实现。 首先第一步255-b运算相当于对b进行按位取反,因此可将8个非门组成如下图的形式: 由于每次做减法时,我...

FAT_mt
昨天
40
0
好程序员大数据学习路线分享函数+map映射+元祖

好程序员大数据学习路线分享函数+map映射+元祖,大数据各个平台上的语言实现 hadoop 由java实现,2003年至今,三大块:数据处理,数据存储,数据计算 存储: hbase --> 数据成表 处理: hive --> 数...

好程序员官方
昨天
61
0
tabel 中含有复选框的列 数据理解

1、el-ui中实现某一列为复选框 实现多选非常简单: 手动添加一个el-table-column,设type属性为selction即可; 2、@selection-change事件:选项发生勾选状态变化时触发该事件 <el-table @sel...

everthing
昨天
21
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部