可能是重复但我在SO上找不到具体问题,所以就是这样。
我很想知道动态改变所有行的高度,通常是因为你不知道用于标签的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)。但就我而言,我的行不会接近那个数字。因此,性能损失可以忽略不计。
提前致谢!
答案 0 :(得分:8)
好问题!事实上,我在一些应用程序中做了类似的事情。
我可以想到几个替代品,但所有这些都是相同的主题。您也可以在sizeWithFont:
内使用heightForRowAtIndexPath:
并取消数组。在这种情况下,如果该操作很昂贵,每次重新计算大小时可能会受到性能损失。
您可以对 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”属性。然后,每次更改字符串的值时,您都可以重新计算字符串的大小。然后,只有一个数组,而不是两个,映射到您的数据源,填充包含字符串的字符串和显示大小的数据类,并在字符串更改时计算值,而不是一次当视图出现时。
无论如何,我很想听听有关这些不同方法的一些评论。
答案 1 :(得分:1)
马修关于将高度放在数据模型中的想法听起来很有趣。这是另一个提出非常类似解决方案的答案:How can I do variable height table cells on the iPhone properly?
答案 2 :(得分:1)
当我滚动tableview(在3gs iPhone上)时,我的UITableView出了问题。我看到了很多滞后。所以我打开时间分析器(非常好的优化工具)和问题是当我调用函数sizeWithFont时。解决此问题的最佳解决方案是在构造函数中调用sizeWithFont。