UITableViewCell通过内容拥抱自动调整大小

时间:2015-08-21 14:58:55

标签: ios objective-c uitableview autolayout constraints

我想要实现的是在其内部拥抱UILabel自动调整单元格。 我能够使它工作,直到我开始拥抱部分。 通过拥抱,我的意思是如果文本非常短,则使UILabel尽可能小。

我准备了一个非常简单的问题示例:

http://s000.tinyupload.com/index.php?file_id=11087347944522931899

在我将尾随约束设置为“500”优先级(低于拥抱,即750)后,一切都很好。 现在看来,尺寸单元格正在减小UILabel的尺寸,但从未增加,所有高度计算都是错误的。

在第一个真正的短片进入后 - 所有这一切都被打破了:

problem

从调试中我发现,一旦UILabel达到8px,它就会变得更大,并且所有高度计算都是以8px宽度完成的。

我找到了一个解决方法,并且在单元格出于任何原因而出列后重置了preferredWidth,但是我不确定是否有更好的方法来解决问题。

我的解决方法是附加项目中的注释(第55行,第81行)ChatTableController.m,我正在寻找合适的解决方案。

2 个答案:

答案 0 :(得分:2)

首先,将标签上的尾随约束设置为> = 20。这让标签缩小了。

你真正的问题是这个方法:

- (void)setBounds:(CGRect)bounds {
    [super setBounds:bounds];

    if (self.numberOfLines == 0 && bounds.size.width != self.preferredMaxLayoutWidth) {
        self.preferredMaxLayoutWidth = self.bounds.size.width;
        [self setNeedsUpdateConstraints];
    }
}

cell.theLabel.preferedMaxLayoutWidthheightForRowAtIndexPath中创建单元格时,最好设置cellForRowAtIndexPath

如果你完全评论这段代码,那么它似乎都有效。

如果每次调用heightForRowAtIndexPath时创建一个新的原型单元格,也可以使代码工作。这就是我的上述功能。

似乎每次调用heightForRowAtIndexPath时,原型单元的重用会导致高度的组合增加。如果向下滚动并备份,就会看到这一点。

所以我会完全删除这个方法,并让约束为你工作。我看到当一行精确到大小而其他一切都紧凑时,单元格会缩小。

在createCellForRowAtIndexPath中设置文本之前,添加以下内容以使布局宽度全屏减去20个边距:

cell.messageLabel.preferredMaxLayoutWidth=self.view.bounds.size.width-40;

之前在heightForRowAtIndexPath中的原型单元格中设置文本:

prototypeCell.messageLabel.preferredMaxLayoutWidth=self.view.bounds.size.width-40;

设置preferredMaxLayoutWidth会导致轮换问题。设置每个单元格意味着每个单元格现在具有特定于方向的约束。要解决此问题,您必须通过将以下内容添加到视图控制器来重新加载表:

- (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    [self.tableView reloadData];
}

最终结果:

enter image description here

答案 1 :(得分:0)

我建议做的是通过测量文本边界来预先计算单元格高度。执行此操作的最简单且性能最差的方法是使用- (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options attributes:(NSDictionary *)attributes context:(NSStringDrawingContext *)context

理想情况下,您希望尽快计算边界。 CoreText 将帮助您解决这个问题。

使用CoreText预先计算文本边界/布局的一个很好的例子是this GitHub repo。

如果您需要更多信息/帮助,请与我们联系。