用两列自动调整 UITableViewCell [英] Autosize UITableViewCell with two columns

查看:21
本文介绍了用两列自动调整 UITableViewCell的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a UITableViewCell that has two columns in it. Each column is a UILabel and each label is multiline (numberOfLines = 0).

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

What I would like is to have the table view cell vertically sized based on whichever label is taller. I have constraints setup for the left right and top of each label, but I am not sure how to add the bottom constraints since it needs to be a constraint on the tallest label.

这是我现在拥有的:

但这就是我想要达到的目标.但左列或右列都可能更高.在图片中,右列较高,但也可能是左列,具体取决于提供给它的数据.

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.

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

I have thought about adding a height constraint to constraint both labels to the same height and then adding the bottom constraint from there, but then the shorter label will not be vertically aligned, or I do not know of a way of aligning them vertically without subclassing UILabel or using UITextView, which I would prefer to not do if possible.

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

Is there a good way to have the table view cell be able to vertically auto-size based on whichever column is taller? Thanks for your help.

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

I have added two additional constraints based on the answer provided. But for some reason I still cannot get it to autosize the table cell. I have the row height set to automatic in Interface Builder. Here are the constraints I have configured currently.

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

Is there anything in the constraints that would prevent the table view cell from increasing in height to match the height of the labels?

我不确定这是否是问题所在,但我尝试按照建议向内容视图添加低优先级高度约束,但我无法添加约束或者我不知道如何添加去做.我可以将高度约束添加到其他视图,但不能添加到表格视图单元格的内容视图.

I am not sure if this is the problem or not, but I tried to add a low priority height constraint to the content view also, as was suggested, but I am unable to add the constraint or I do not know how to do that. I can add a height constraint to other views, but not to the content view of the table view cell.

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

Here are the constraints in code. This is in a UITableViewCell subclass and this code runs as part of the initialization of the cell.

[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,并且我认为内容拥抱和内容压缩阻力优先级设置为我认为应该正确的值,它也会被截断.

Here is what it looks like when run on the device. The labels are all short, except the first one, which is supposed to span several lines. But for some reason, it is being truncated even though I have the number of lines set to 0 and I think the content hugging and content compression resistance priorities set to what I think should be correct.

这是我的标签的定义方式:

Here are how my labels are defined:

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

推荐答案

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

Yes, it's pretty straightforward when you understand about constraint inequalities and priorities. Here, the label on the left is longer:

这里,右边的标签更长了:

Here, the label on the right is longer:

代表表格视图单元格的黄色视图的大小与标签中的较大者一致.

The yellow view, which stands in for a table view cell here, is sized to the larger of the labels.

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

How is that done? In addition to the labels being pinned top, left, and right in the normal way, the superview (yellow view) bottom has two greater-than-or-equal constraints, one to the bottom of each label; and it is itself given a very small height at a very low priority (as a way of telling the layout engine to make the height as small as possible while still obeying the inequalities, which would otherwise be ambiguous).

编辑似乎有人怀疑这是否适用于实际的表格视图,所以这里证明它确实有效.

EDIT There appears to be some doubt that this would work for an actual table view, so here's proof that it does.

这篇关于用两列自动调整 UITableViewCell的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆