iOS 7/8 UITableView Cell:两个UILabel,动态高度,自动布局,可变行高

时间:2014-09-26 09:05:09

标签: ios uitableview uilabel autolayout

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

我将内容拥抱优先级和压缩阻力设置为1000 = =我收到歧义警告

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

我还玩过内在尺寸:默认或占位符(有几个高度和宽度),但它也没有帮助。

有人建议可以做些什么吗?

3 个答案:

答案 0 :(得分:18)

我终于开始工作了。解决方案是我明确地将首选宽度设置为当前帧宽度。 所以基本上检查标签>中的显式复选标记。尺寸检查器中的首选宽度。

参考:http://www.raywenderlich.com/73602/dynamic-table-view-cell-height-auto-layout 下载示例代码并查看故事板设置。

答案 1 :(得分:1)

对我来说,这需要几件事。

  • 除了设置内容拥抱和阻力正确
  • 我必须创建一个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

除了在tableView heightForRowAtIndexPath:中获取高度之前在单元格上调用layoutIfNeeded之外,在使用contentView上的systemLayoutSizeFittingSize:方法之前准备好约束。看起来像这样:

- (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;
}

参考文献:

答案 2 :(得分:0)

对于我来说,设置内容拥抱优先级和内容压缩阻力优先级低于正常工作的元素之一。