iOS 7/8 UITableView单元格:两个具有动态高度的UILabel,具有可变行高的自动布局

iOS 7/8 UITableView单元格:两个具有动态高度的UILabel,具有可变行高的自动布局,ios,uitableview,uilabel,autolayout,Ios,Uitableview,Uilabel,Autolayout,因此,当我只有一个标签根据字符串的长度更改高度时,我可以使用自动布局设置动态高度大小调整。 我的问题是,如果我添加另一个UILabel也应该这样做,那么事情就不会成功 我将内容拥抱优先级和压缩阻力都设置为1000,因为这两个==我收到了歧义警告 如果我将第二个UILabel的内容拥抱(垂直)设置为999或250,则效果很好,但前提是第二个标签有两行或更多行。如果第二个标签为空或只有一行,则行的高度IndexPath systemLayoutSizeFittingSize:UILayoutFitt

因此,当我只有一个标签根据字符串的长度更改高度时,我可以使用自动布局设置动态高度大小调整。 我的问题是,如果我添加另一个UILabel也应该这样做,那么事情就不会成功

我将内容拥抱优先级和压缩阻力都设置为1000,因为这两个==我收到了歧义警告

如果我将第二个UILabel的内容拥抱(垂直)设置为999或250,则效果很好,但前提是第二个标签有两行或更多行。如果第二个标签为空或只有一行,则行的高度IndexPath systemLayoutSizeFittingSize:UILayoutFittingCompressedSize高度将返回较大的值,并且单元格具有较大的空格

我还使用了固有的大小:默认值或占位符(带有两个高度和宽度),但它也没有帮助


谁有什么建议可以做吗?

我终于成功了。我的解决方案是将首选宽度显式设置为当前帧宽度。 因此,基本上检查尺寸检查器中标签>首选宽度中的显式复选标记

参考:
下载示例代码并查看故事板设置

对于我来说,将内容拥抱优先级和内容压缩阻力优先级设置为较低的一个元素,效果与预期一样。

对于我来说,这需要综合考虑多种因素

  • 除了正确设置内容拥抱和阻力之外
  • 我必须创建UILabel的子类来处理标签的preferredMaxLayoutWidth
  • 并纠正intrinsicContentSize中的错误
UILabel子类的结果如下:

@implementation LabelDynamicHeight

- (void)layoutSubviews
{
    [super layoutSubviews];

    self.preferredMaxLayoutWidth = self.frame.size.width;

    [super layoutSubviews];
}

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

    if (self.numberOfLines == 0)
    {
        CGFloat boundsWidth = CGRectGetWidth(bounds);
        if (self.preferredMaxLayoutWidth != boundsWidth)
        {
            self.preferredMaxLayoutWidth = boundsWidth;
            [self setNeedsUpdateConstraints];
        }
    }
}

- (CGSize)intrinsicContentSize
{
    CGSize size = [super intrinsicContentSize];

    if (self.numberOfLines == 0)
    {
        // There's a bug where intrinsic content size may be 1 point too short
        size.height += 1;
    }

    return size;
}

@end
- (CGFloat)tableView:( UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = ...;
    CGFloat height = cell.frame.size.height;
    if (cell.dynamicHeight)
    {
        // https://stackoverflow.com/a/26351692/1840269
        [cell layoutIfNeeded];
        height = cell.frame.size.height;

        CGSize size = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
        if (size.height > height)
            height = size.height;
    }
    return height;
}
除此之外,在获取
tableView中的高度之前,需要在单元格上调用layoutifn。heightForRowAtIndexPath:
在contentView上使用
systemLayoutSizeFittingSize:
方法之前,必须准备好约束。看起来像这样:

@implementation LabelDynamicHeight

- (void)layoutSubviews
{
    [super layoutSubviews];

    self.preferredMaxLayoutWidth = self.frame.size.width;

    [super layoutSubviews];
}

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

    if (self.numberOfLines == 0)
    {
        CGFloat boundsWidth = CGRectGetWidth(bounds);
        if (self.preferredMaxLayoutWidth != boundsWidth)
        {
            self.preferredMaxLayoutWidth = boundsWidth;
            [self setNeedsUpdateConstraints];
        }
    }
}

- (CGSize)intrinsicContentSize
{
    CGSize size = [super intrinsicContentSize];

    if (self.numberOfLines == 0)
    {
        // There's a bug where intrinsic content size may be 1 point too short
        size.height += 1;
    }

    return size;
}

@end
- (CGFloat)tableView:( UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = ...;
    CGFloat height = cell.frame.size.height;
    if (cell.dynamicHeight)
    {
        // https://stackoverflow.com/a/26351692/1840269
        [cell layoutIfNeeded];
        height = cell.frame.size.height;

        CGSize size = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
        if (size.height > height)
            height = size.height;
    }
    return height;
}
参考资料:

  • 适合内容拥抱和抵抗:
  • preferredMaxLayoutWidth操作的说明:
  • 具有intrinsicContentSize修复的UILabel子类的灵感:

你的UILabel是固定宽度的吗?不,我支持不同的设备尺寸,因此宽度也会随之变化。对我来说,缺少的元素是为我的单元格标题和字幕标签设置内容拥抱和内容压缩优先级,如Ray Wenderlich教程所示。非常感谢Wenderlich文章!它几乎在瞬间起作用。在我花了好几天的时间在互联网上搜索之前,动态单元格高度在使用NIAttributed标签时有效吗?我不能让它工作使用NIAttributedLabel,但在UILabel工作完美,请帮助