具有动态高度的 UITableViewCell 中的 UILabel

Posted

技术标签:

【中文标题】具有动态高度的 UITableViewCell 中的 UILabel【英文标题】:UILabel in a UITableViewCell With Dynamic Height 【发布时间】:2013-01-22 13:49:34 【问题描述】:

我在 UITableView 中实现动态行高时遇到了一些问题 - 但我遇到问题的不是单元格,而是单元格内的 UILabel。

单元格只包含一个用于显示文本的 UILabel。我的 tableView:heightForRowAtIndexPath: 通过使用 NSString 的 sizeWithFont: 方法计算标签的高度来正确调整每个单元格的大小。

我有一个 UITableViewCell 的子类,它只包含连接在情节提要中的 UILabel 属性。在情节提要中,我已将其行数设置为 0,因此它将根据需要使用尽可能多的行数,并且我已将其 lineBreak 设置为 Word Wrap。

这是我设置单元格的方式:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath  *)indexPath

    ExpandCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"  forIndexPath:indexPath];

   SomeObject *object = self.tableObjects[index.row];

    cell.myLabel.text = [object cellText];

    [cell.myLabel sizeToFit];

    return cell;

当我构建这个时,我得到了我的表格视图,其中单元格的大小都调整到了其内容的正确高度,但是标签都是 1 行,只是从单元格的一侧延伸出来。但是,如果我滚动表格以使单元格离开屏幕,然后滚动回它们,它们的标签将被正确调整大小,并且单元格将看起来与我最初的预期相同。

我还尝试使用与计算行高相同的方法来计算标签框架,但我得到了相同的行为 - 它无法正确绘制,直到它滚出屏幕并重新打开。

我找到了两种解决方法,但都不是可接受的解决方案。

首先,如果在 viewDidAppear: 我在我的 tableview 上调用 reloadData,单元格和标签第一次正确地绘制自己。这不适用于我的情况,因为我将在此表中添加和删除单元格,并且我不想在每次添加单元格时都调用 reloadData。

第二种解决方法对我来说似乎很奇怪 - 如果我将字体设置保留为 UILabel 上的默认系统字体 17,则单元格会正确绘制自己。一旦我更改了字体大小,它就会恢复到不正确绘制标签的行为,直到它离开屏幕并返回,或者在 tableView 上调用 reloadData。

如果能对此提供任何帮助,我将不胜感激。

【问题讨论】:

这篇文章正确回答了您的问题:***.com/questions/8903369/…。如果您以前从未创建过动态大小的单元格,这可能会有点棘手,但并不太难。 我不明白该答案中的代码与我正在做的事情有何不同。我在 cellForRowAtIndexPath 中设置了标签的框架,但直到下一次重绘时才会应用该框架。还是我错过了什么? 你在实现 heightForRowAtIndexPath 吗? 是的。每次都正确计算单元格高度。它是单元格内部的标签,直到重新绘制后才能获得正确的帧。 你可以使用 ios6 NSConstraints 吗?其超级视图单元格的标签尾随和前导空间可以保持不变。因此,如果单元格调整大小,标签也会调整大小。 【参考方案1】:

我最终通过分配/初始化 cellForRowAtIndexPath 中的标签解决了这个问题。我不完全确定为什么这是一个解决方案 - 但似乎我遇到的问题与情节提要如何(或者何时,也许?)在单元格内创建对象有关。如果我在 cellForRowAtIndexPath 的单元格中分配/初始化标签,则所有内容都会正确加载和调整大小。

所以...我目前的解决方法是检查单元格中是否有我的自定义标签。如果没有,我分配/初始化标签并将其放入单元格中。如果它确实有一个,例如在它的一个已出列的单元格中,那么我只需将文本设置在已经存在的标签中。

不确定它是否是最好的解决方案,但目前可以使用。

【讨论】:

我遇到了类似的问题。我通过从 tableView:cellForRowAtIndexPath: 中删除 [cell.myLabel sizeToFit] 来解决它。然后使用情节提要,将约束条件 Top Space 添加到 Superview,Bottom Space 到 Superview。【参考方案2】:

我最终通过取消选中 IB 中的 AutoSizing 复选框解决了这个问题。目前尚不清楚自动布局为何会导致此问题。

【讨论】:

【参考方案3】:

我遇到了同样的问题,我最终通过在返回单元格之前调用 [cell layoutIfNeeded] 来解决它

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath  *)indexPath 
ExpandCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"  forIndexPath:indexPath];
SomeObject *object = self.tableObjects[index.row];

cell.myLabel.text = [object cellText];

[cell layoutIfNeeded];

return cell; 

【讨论】:

以上是关于具有动态高度的 UITableViewCell 中的 UILabel的主要内容,如果未能解决你的问题,请参考以下文章

具有动态高度的 UITableView 和 UITableViewCell 仅在 WillDisplay 中知道

Swift / 如何使用具有动态高度的 UITextView INSIDE UITableViewCell 与动态高度

Autolayout - 当一个视图具有动态高度时,在 UITableViewCell 中垂直居中两个视图

具有动态内容、动态布局和动态高度的 UITableViewCell

具有动态高度的 UITableViewCell 中的 UILabel

UITableViewCell 具有嵌入式垂直堆栈视图设置,具有自动布局和动态高度