2011-09-27 19 views
10

可能是重复的,但我无法找到关于SO的具体问题,所以在这里。绘制动态UITableView行高的最佳做法

我很好奇动态改变所有行的高度,通常是因为你不知道用于标签的NSString的长度。

我知道你必须使用此委托方法来改变行高:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 

的问题是之前小区创建此委托方法被调用(即cellForRowAtIndexPath之前调用)。

所以,我想到的是在viewWillAppear中创建一个模拟单元格,并将一个单元格高度添加到映射到表视图数据源的数组(这在我的情况下也是一个数组)。

viewWillAppear实现这一个重要的方法来获得高度:

[NSString sizeWithFont: constrainedToSize: lineBreakMode:]

然后在heightForRowAtIndexPath我可以返回单元格的高度,像这样:

//cellHeights is an ivar populated in viewWillAppear 
return [[cellHeights objectAtIndex:indexPath.row] floatValue]; 

我在想,如果有一个更好的方式来动态改变行高?

我知道这会降低大量行(大于1000,我相信)的性能。但就我而言,我的排不会接近那个数字。所以性能影响可以忽略不计。

在此先感谢!

回答

8

伟大的问题!事实上,我在一些应用程序中做了类似的事情。

我可以考虑一些替代方案,但所有这些都沿着相同的主题。您也可以在heightForRowAtIndexPath:内部使用sizeWithFont:,并取消该阵列。在这种情况下,如果该操作很昂贵,那么每次重新计算大小时都可能会遇到性能问题。

你可以做的heightForRowAtIndexPAth:内cellHeights阵列的“懒加载”,所以它可能是这个样子:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 
    if ([cellHeights objectAtIndex:indexPath.row] == nil) { 
     ... calculate height and store it in the array at the correct index... 
    } 

    return [[cellHeights objectAtIndex:indexPath.row] floatValue]; 
} 

的优势在这里,我想的是,你将只计算高度对于肯定要加载的单元格。如果您在viewWillAppear中进行计算,我想您最终会对每个单元格执行此操作,无论它是否显示?

最后,您可以将大小放在您的数据模型本身中。例如,如果它是一个字符串数组,您可以创建一个具有两个属性的类:一个字符串和一个“representationSize”属性。然后,您可以在每次更改字符串的值时重新计算字符串的大小。然后,只有一个数组,而不是两个映射到您的数据源上的数组,填充包含字符串的字符串和显示大小的数据类,并且该值将在字符串更改时计算,而不是一次当视图出现时。

无论如何,我很想听听关于这些不同方法的一些评论。

+0

太糟糕了。我也希望得到更多的回应。感谢您的输入! –

1

我在我的UITableView,当我滚动tableview(在3gs iPhone上)也有问题。我看到很多滞后。所以我打开时间剖析器(非常好的优化工具),问题是当我调用函数sizeWithFont。解决此问题的最佳解决方案是在构造函数中调用sizeWithFont。