使用intrinsicContentSize的动态高度的UIView

11

我正在尝试创建一个自定义容器视图,其中包含UIImageView和多行UILabel作为子视图。为了使该视图与自动布局良好地配合使用,我正在重写intrinsicContentSize,代码如下:

- (CGSize)intrinsicContentSize
{
    return [self sizeThatFits:self.bounds.size];
}

在 sizeThatFits 中计算出的大小具有相同的宽度,并调整高度,以使标签和图像不被裁剪。这样做效果很好,但我惊讶地看到在文档中有以下评论:

这个内在大小必须独立于内容框架,因为无法动态地向布局系统通信基于改变的高度而改变的宽度,例如。

如果是这样,那么自动布局如何根据其宽度和内容调整视图的当前高度?我是否应该以不同的方式来处理这个问题?


如果您想避免内容被裁剪,必须增加容器视图的压缩阻力优先级。 - Max MacLeod
1
压缩阻力是视图抵抗变小于其固有内容大小的优先级。如果固有内容大小不正确,则这将没有什么用处。 - Tark
4个回答

7
为了回答我的问题,似乎没有适用于此情况的自动布局解决方案。从UILabel中寻找灵感,这里的问题已经通过添加属性preferredMaxLayoutWidth来解决,可以在内在内容大小计算期间将其用作约束宽度。任何自定义视图都需要使用类似的方法。

是的,似乎Autolayout几乎没有帮助来完成它。你的答案让我想到了一种方法,即当preferredMaxLayoutWidth > 0.0f时限制视图宽度,否则就不限制 - 在内在内容大小计算中使用一个大浮点数(例如99999.0f)作为宽度。 - Yevhen Dubinin

1
我认为文档的意思是,你的containerView可能有一个placeHolderFrame作为内容框架。
内在大小不应与内容框架相关,而只应与其自身的子内容相关。例如,您的图像和UILabel。
您应该从标签和图像计算高度和宽度。这应该很容易,因为它们都具有内在大小。
这只是我的想法...

3
placeHolderFrame是什么?同样,content frame又是什么呢?标签是一个多行标签,不知道它的高度,必须先知道视图有多少宽度可以包裹文字。 - Tark

0
我猜你可以使用UILabel的新preferredMaxLayoutWidth属性来正确布局标签,并使用其他方法来布局其他内容。
就像这样:
- (void)layoutSubviews
{
    ...
    [super layoutSubviews]; // get width from solved constraints
    label.preferredMaxLayoutWidth = label.frame.size.width; // use it
    [super layoutSubviews]; // update height of a label (probably intrinsicContentSize)
    ...
}

这里的问题不在于如何正确地布局视图,而在于告诉布局系统视图的内在高度,以便根据其内容给出正确的高度。 - Tark
我的观点是关于标签的内在内容大小。通过preferredMaxLayoutWidth,可以更加友好地更新自动布局(也许这就是苹果建议的做法)。 - MANIAK_dobrii

-1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接