不要重复创建不必要的table cell
前面说了,UITableView只需要一屏幕的UITableViewCell对象即可。因此在cell不可见时,可以将其缓存起来,而在需要时继续使用它即可。
而UITableView也提供了这种机制,只需要简单地设置一个identifier即可:
1
|
static NSString *CellIdentifier = @"xxx";
|
不要做多余的绘制工作。
在实现drawRect:的时候,它的rect参数就是需要绘制的区域,这个区域之外的不需要进行绘制。
例如上例中,就可以用CGRectIntersectsRect、CGRectIntersection或CGRectContainsRect判断是否需要绘制image和text,然后再调用绘制方法。
下面是转载于 BLOG: SUNNYXX – 优化UITableViewCell高度计算的那些事
他们也在维护一个开源的扩展,UITableView+FDTemplateLayoutCell,让高度计算这个事情变的前所未有的简单,也受到了很多星星的支持,github链接请戳我
rowHeight
UITableView
是我们再熟悉不过的视图了,它的 delegate 和 data source 回调不知写了多少次,也不免遇到 UITableViewCell 高度计算的事。UITableView 询问 cell 高度有两种方式。
一种是针对所有 Cell 具有固定高度的情况,通过:
1
|
self.tableView.rowHeight = 88;
|
上面的代码指定了一个所有 cell 都是 88 高度的 UITableView,对于定高需求的表格,强烈建议使用这种(而非下面的)方式保证不必要的高度计算和调用。rowHeight属性的默认值是 44,所以一个空的 UITableView 显示成那个样子。
另一种方式就是实现 UITableViewDelegate
中的:
1
|
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
|
需要注意的是,实现了这个方法后,rowHeight
的设置将无效。所以,这个方法适用于具有多种 cell 高度的 UITableView。
estimatedRowHeight
这个属性 iOS7 就出现了, 文档是这么描述它的作用的:
If the table contains variable height rows, it might be expensive to calculate all their heights when the table loads. Using estimation allows you to defer some of the cost of geometry calculation from load time to scrolling time.
恩,听上去蛮靠谱的。我们知道,UITableView 是个 UIScrollView,就像平时使用 UIScrollView
一样,加载时指定 contentSize 后它才能根据自己的 bounds、contentInset、contentOffset 等属性共同决定是否可以滑动以及滚动条的长度。而 UITableView 在一开始并不知道自己会被填充多少内容,于是询问 data source 个数和创建 cell,同时询问 delegate 这些 cell 应该显示的高度,这就造成它在加载的时候浪费了多余的计算在屏幕外边的 cell 上。和上面的 rowHeight
很类似,设置这个估算高度有两种方法:
1
|
self.tableView.estimatedRowHeight = 88;
|
有所不同的是,即使面对种类不同的 cell,我们依然可以使用简单的 estimatedRowHeight
属性赋值,只要整体估算值接近就可以,比如大概有一半 cell 高度是 44, 一半 cell 高度是 88, 那就可以估算一个 66,基本符合预期。
使用UITableView+FDTemplateLayoutCell
无疑是解决算高问题的最佳实践之一,既有 iOS8 self-sizing 功能简单的 API,又可以达到 iOS7 流畅的滑动效果,还保持了最低支持 iOS6。
使用起来大概是这样:
<uitableview+fdtemplatelayoutcell.h>
1
|
- (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];
}];
}
|
写完上面的代码后,你就已经使用到了:
-dequeueCellForReuseIdentifier:
方法 lazy 创建并保存,所以要求这个 ReuseID 必须已经被注册到了 UITableView 中,也就是说,要么是 Storyboard 中的原型 cell,要么就是使用了 UITableView 的 -registerClass:forCellReuseIdentifier:
或 -registerNib:forCellReuseIdentifier:
其中之一的注册方法。-systemLayoutSizeFittingSize:
如果你觉得这个工具能帮得到你,整合到工程也十分简单。
使用 cocoapods:
1
|
pod search UITableView+FDTemplateLayoutCell
|
欢迎使用和支持这个工具,有 bug 请随时反馈哦~
再复习下 github 地址: https://github.com/forkingdog/UITableView-FDTemplateLayoutCell
原文:http://www.cnblogs.com/SensenCoder/p/5134634.html