绘制动态UITableView行高的最佳实践

Dav*_*Nix 10 iphone objective-c uitableview ios

可能是重复但我在SO上找不到具体问题,所以在这里.

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

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

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
Run Code Online (Sandbox Code Playgroud)

问题是这个委托方法在创建单元格之前调用(即之前调用cellForRowAtIndexPath).

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

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

[NSString sizeWithFont: constrainedToSize: lineBreakMode:]

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

//cellHeights is an ivar populated in viewWillAppear
return [[cellHeights objectAtIndex:indexPath.row] floatValue];
Run Code Online (Sandbox Code Playgroud)

我想知道是否有更好的方法来动态改变行高?

我意识到这会降低大量行的性能(我相信大于1000).但就我而言,我的行不会接近那个数字.因此,性能损失可以忽略不计.

提前致谢!

Mat*_*ham 8

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

我可以想到几个替代方案,但所有这些都是相同的主题.你也可以只使用sizeWithFont:内部heightForRowAtIndexPath:并取消数组.在这种情况下,如果该操作很昂贵,每次重新计算大小时可能会受到性能影响.

你可以对其中的cellHeights数组进行"延迟加载" , heightForRowAtIndexPAth: 所以它可能看起来像这样:

- (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];
}
Run Code Online (Sandbox Code Playgroud)

我在这里考虑的优点是你只计算肯定会加载的单元格的高度.如果你进行计算viewWillAppear,我想你最终会为每个细胞做这个,不管它是否显示?

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

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