自动调整 UITableViewCell 的两列大小

2024-02-04

我有一个 UITableViewCell,其中有两列。每列都是一个 UILabel,每个标签都是多行 (numberOfLines = 0)。

我想要的是根据较高的标签来垂直调整表格视图单元格的大小。我为每个标签的左右和顶部设置了约束,但我不确定如何添加底部约束,因为它需要成为最高标签的约束。

这是我现在所拥有的:

But this is what I am trying to achieve. But either the left or the right column could be taller. In the picture, the right column is taller, but it just as well could be the left column depending on the data supplied to it. enter image description here

我考虑过添加高度约束来将两个标签约束到相同的高度,然后从那里添加底部约束,但是较短的标签将不会垂直对齐,或者我不知道如何在不子类化的情况下垂直对齐它们UILabel 或使用 UITextView,如果可能的话我宁愿不这样做。

有没有一种好方法可以让表视图单元格能够根据较高的列垂直自动调整大小?感谢您的帮助。


Update

我根据提供的答案添加了两个额外的约束。但由于某种原因,我仍然无法让它自动调整表格单元格的大小。我在 Interface Builder 中将行高设置为自动。这是我当前配置的约束。

约束中是否有任何内容会阻止表视图单元格增加高度以匹配标签的高度?

我不确定这是否是问题,但我也尝试按照建议向内容视图添加低优先级高度约束,但我无法添加约束或者我不知道该怎么做。我可以向其他视图添加高度约束,但不能向表视图单元格的内容视图添加高度约束。

Update 2

这是代码中的约束。这是在 UITableViewCell 子类中,此代码作为单元格初始化的一部分运行。

[self addSubview:self.firstLabel];
[self addSubview:self.secondLabel];

NSLayoutConstraint *heightConstraint = [self.heightAnchor constraintEqualToConstant:1.0f];
[heightConstraint setPriority:50];

[NSLayoutConstraint activateConstraints:@[
    [self.firstLabel.leadingAnchor constraintEqualToAnchor:self.contentView.layoutMarginsGuide.leadingAnchor],
    [self.firstLabel.topAnchor constraintEqualToAnchor:self.contentView.layoutMarginsGuide.topAnchor constant:0.0f],
    [self.firstLabel.trailingAnchor constraintEqualToAnchor:self.centerXAnchor constant:-4.0f],
    
    [self.secondLabel.leadingAnchor constraintEqualToAnchor:self.centerXAnchor constant:4.0f],
    [self.secondLabel.firstBaselineAnchor constraintEqualToAnchor:self.firstLabel.firstBaselineAnchor],
    [self.secondLabel.trailingAnchor constraintEqualToAnchor:self.contentView.layoutMarginsGuide.trailingAnchor],
    
    [self.contentView.heightAnchor constraintGreaterThanOrEqualToAnchor:self.firstLabel.heightAnchor constant:8.0f],
    [self.contentView.heightAnchor constraintGreaterThanOrEqualToAnchor:self.secondLabel.heightAnchor constant:8.0f],
    
    heightConstraint
]];

这是在设备上运行时的样子。除了第一个标签之外,所有标签都很短,它应该跨越几行。但由于某种原因,即使我将行数设置为 0,它也会被截断,并且我认为内容拥抱和内容压缩阻力优先级设置为我认为应该正确的值。

以下是我的标签的定义方式:

- (UILabel *)firstLabel {
    if (!self->_firstLabel) {
        self->_firstLabel = [[UILabel alloc] init];
        self->_firstLabel.translatesAutoresizingMaskIntoConstraints = NO;
        self->_firstLabel.numberOfLines = 0;
        self->_firstLabel.userInteractionEnabled = NO;
        self->_firstLabel.contentMode = UIViewContentModeScaleToFill;
        [self->_firstLabel setContentHuggingPriority:251 forAxis:UILayoutConstraintAxisHorizontal];
        [self->_firstLabel setContentHuggingPriority:251 forAxis:UILayoutConstraintAxisVertical];
        [self->_firstLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
        [self->_firstLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];
        self->_firstLabel.textAlignment = NSTextAlignmentNatural;
        self->_firstLabel.lineBreakMode = NSLineBreakByTruncatingTail;
        self->_firstLabel.baselineAdjustment = UIBaselineAdjustmentAlignBaselines;
        self->_firstLabel.adjustsFontSizeToFitWidth = NO;
        
        //TODO: remove this
        self->_firstLabel.backgroundColor = [UIColor orangeColor];
    }
    return self->_firstLabel;
}

- (UILabel *)secondLabel {
    if (!self->_secondLabel) {
        self->_secondLabel = [[UILabel alloc] init];
        self->_secondLabel.translatesAutoresizingMaskIntoConstraints = NO;
        self->_secondLabel.numberOfLines = 0;
        self->_secondLabel.userInteractionEnabled = NO;
        self->_secondLabel.contentMode = UIViewContentModeScaleToFill;
        [self->_secondLabel setContentHuggingPriority:251 forAxis:UILayoutConstraintAxisHorizontal];
        [self->_secondLabel setContentHuggingPriority:251 forAxis:UILayoutConstraintAxisVertical];
        [self->_secondLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
        [self->_secondLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];
        self->_secondLabel.textAlignment = NSTextAlignmentNatural;
        self->_secondLabel.lineBreakMode = NSLineBreakByTruncatingTail;
        self->_secondLabel.baselineAdjustment = UIBaselineAdjustmentAlignBaselines;
        self->_secondLabel.adjustsFontSizeToFitWidth = NO;
        
        //TODO: remove this
        self->_secondLabel.backgroundColor = [UIColor yellowColor];
    }
    return self->_secondLabel;
}

是的,当您了解约束不等式和优先级时,这非常简单。这里,左侧的标签更长:

在这里,右侧的标签更长:

黄色视图代表表格视图单元格,其大小适合较大的标签。

这是怎么做到的?除了以正常方式将标签固定在顶部、左侧和右侧之外,超级视图(黄色视图)底部还有两个大于或等于约束,一个到每个标签的底部;并且它本身以非常低的优先级被赋予一个非常小的高度(作为告诉布局引擎使高度尽可能小的同时仍然遵守不等式的一种方式,否则这将是不明确的)。


EDIT似乎有人怀疑这是否适用于实际的表视图,因此这里有证据证明它确实有效。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

自动调整 UITableViewCell 的两列大小 的相关文章

随机推荐