Ios 可变长度标签、tableview行高和自动布局

Ios 可变长度标签、tableview行高和自动布局,ios,uitableview,uilabel,autolayout,Ios,Uitableview,Uilabel,Autolayout,关于SO以及如何根据子视图的大小计算UITableView行的必要高度,有很多很好的信息。我在这里应用的典型示例是一个单元格,其中包含一个具有可变长度文本的标签 通常的建议是在tableview的高度为RowAtIndexPath:中使用大小为font:constrainedToSize:lineBreakMode:。但我看到的大多数例子都使用了基于标签宽度的“神奇”数字 CGSize constraint = CGSizeMake(224.0, MAXFLOAT); //224 is kno

关于SO以及如何根据子视图的大小计算UITableView行的必要高度,有很多很好的信息。我在这里应用的典型示例是一个单元格,其中包含一个具有可变长度文本的标签

通常的建议是在tableview的
高度为RowAtIndexPath:
中使用
大小为font:constrainedToSize:lineBreakMode:
。但我看到的大多数例子都使用了基于标签宽度的“神奇”数字

CGSize constraint = CGSizeMake(224.0, MAXFLOAT); //224 is known to be the width available
CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:NSLineBreakByWordWrapping];
一些更好的示例可能会使用tableview的边界,然后减去单元格中其他视图的幻数或常量,这至少会更清楚一些(如果边界在旋转等过程中发生变化,效果会更好)

这是常见的方法,但似乎缺乏。谁能说其他单元格子视图的宽度,甚至字体,保证不会改变(或者在这两个地方都会努力改变)

我决定让单元负责提供这个高度。细胞总是知道它的属性。为了实现这一点,我首先让单元格中的所有布局代码引用一些局部常量。然后,我在自定义单元格类中添加了一个类方法,它可以根据自己的字体和大小常量返回任何给定文本段所需的高度

+ (CGFloat)heightRequiredForText:(NSString *)text usingWidth:(CGFloat)width
{
    //a class method that tells the caller how much height is needed for the provided text, based on the cell's size and font constants
    CGSize constraintSize = CGSizeMake(width - kMargin - kGap - kMargin - kCheckboxWidth, MAXFLOAT);
    CGRect bounds = [text boundingRectWithSize:constraintSize
                                                options:NSStringDrawingUsesLineFragmentOrigin
                                             attributes:@{NSFontAttributeName:self.labelFont}
                                                context:nil];
    return bounds.size.height;
}
这允许UITableViewController简单地提供文本和当前边界的宽度(即tableview的宽度)。字体和布局可以在cell子类中更改,一切都可以继续“正常工作”

问题1

作为旁注,这合理吗?有没有更好的方法来实现同样的目标

问题2

这是我对这种(以及更标准的)方法的主要问题。当单元格处于编辑模式时,标签的宽度将更改以适应编辑附件。由于行高度是恒定的,并且标签使用自动布局,因此其高度会增加

所需的行为是使标签的高度保持不变,必要时应使用截断


我在哪里以及如何实现这一点?我应该在单元格的集合中做些什么吗?也许添加另一个约束来限制高度,并启用截断,在编辑==否时应用相反的约束?“滑动删除”模式如何?我不认为这会触发设置编辑?那么layoutSubview呢?我可以在那里做些什么吗?

我尝试了很多方法-最接近的方法是覆盖layoutSubview,测试用户是否切换到编辑模式,如果是,首先捕获标签的固有高度,然后添加临时约束以强制执行它(当退出编辑模式时,它被删除)。除了少数边缘情况外,它工作得很好

但后来我开始考虑更多的自动布局。我试图实现什么?我不希望标签在宽度减小时变得更高。这是一个非常简单的约束:

[self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:self.label
                                                                    attribute:NSLayoutAttributeHeight
                                                                    relatedBy:NSLayoutRelationLessThanOrEqual
                                                                       toItem:self.contentView
                                                                    attribute:NSLayoutAttributeHeight
                                                                   multiplier:1
                                                                     constant:0]];
添加此附加约束效果良好。请注意,我还在编辑时将换行模式切换为截断:


我推荐的方法是用于这类事情。
[self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:self.label
                                                                    attribute:NSLayoutAttributeHeight
                                                                    relatedBy:NSLayoutRelationLessThanOrEqual
                                                                       toItem:self.contentView
                                                                    attribute:NSLayoutAttributeHeight
                                                                   multiplier:1
                                                                     constant:0]];