几乎每次我为客户编写应用程序时,我都必须实现某种“黑客”以使UITableViewCell
动态变为正确的高度。根据细胞的含量,这可能会有所不同。
我通常最终会运行代码,格式化单元格两次,一次在heightForRowAtIndexPath:
,然后再在cellForRowAtIndexPath:
。然后我使用数组或字典来存储高度或格式化的单元格对象。
在过去的两年里,我可能已经编写并重写了这段代码20次。 Apple为什么按此顺序实施它?配置单元格会更加直接,然后在cellForRowAtIndexPath:
或heightForRowAtIndexPath:
之后不久设置高度。
现有订单是否有充分理由?有没有更好的方法来处理它?</ p>
答案 0 :(得分:8)
最佳猜测:UITableView
需要知道所有单元格的总高度,以便它可以知道滚动条的滚动百分比和其他需求。
答案 1 :(得分:5)
实际上,在iOS 7中,它不必以这种方式工作。您现在可以为行设置估计高度,并仅在实际需要该行时计算每行的实际高度。 (我认为这正是因为人们的投诉与你的投诉相同:“为什么我必须两次这样做?”)
因此,您可以推迟高度计算,然后在第一次出现该行时将其记忆(这是一个简单的单节表,但如果您有多个部分,则很容易调整它):
- (void)viewDidLoad {
[super viewDidLoad];
// create empty "sparse array" of heights, for later
NSMutableArray* heights = [NSMutableArray new];
for (int i = 0; i < self.modeldata.count; i++)
[heights addObject: [NSNull null]];
self.heights = heights;
self.tableView.estimatedRowHeight = 40; // new iOS 7 feature
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
int ix = indexPath.row;
if ([NSNull null] == self.heights[ix]) {
h = // calculate _real_ height here, on demand
self.heights[ix] = @(h);
}
return [self.heights[ix] floatValue];
}
您提供了一个估计的高度,所以所有高度都不预先要求。在该行实际出现在界面之前,系统会要求您输入一个高度,因为它最初是显示的,或者是因为您或用户滚动显示它。
注意另请注意,如果您使用dequeueReusableCellWithIdentifier:forIndexPath:
,则的单元格已经具有正确的最终高度。这就是这种方法的重点(而不是早期的dequeueReusableCellWithIdentifier:
)。