intrinsic content size

2019-07-16  本文已影响0人  高思阳

为什么UILabel在使用Masonry的时候,不需要给出宽度和高度约束?

自动布局的关键就是给出正确且完整的约束。那么看一下下面的例子给出的例子约束是否完整:

(这里使用Masonry来描述约束,可以参考https://github.com/SnapKit/Masonry,但是我觉得直接看也能够看得懂了)

    UILabel *label = [[UILabel alloc] init];
    label.font = [UIFont systemFontOfSize:15];
    label.text = @"Hello";
    [self.view addSubview:label];
    [label mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.view.mas_left).offset(16);
        make.top.equalTo(self.view.mas_top).offset(16);
    }];

这里只定义了两个约束,left 和 top,只够计算出frame的originX和orginY,没有width和height。那么是不是属于不完整的约束呢?其实在这里给出的约束已经是完整的了。因为对于UILabel这个控件而言 ,只要通过其font和text系统就可以计算出Label该有的长度和宽度。这里的长度和宽度就是UILabel的 intrinsic content size(固有属性)。

官方文档给出的视图与intrinsic content size:

一般都是用约束来定义视图的位置和尺寸的。可是,某些视图会根据当前内容生成出一个自然尺寸。这个尺寸即可参考着叫做 intrinsic content size 。比如,一个按钮的 intrinsic content size 就是它的标题加上一个小边缘。

不是所有的视图都有 intrinsic content size,对于普通视图来说,intrinsic content size 可以定义出视图的宽、高或者二者全部。下面的表格3-1中列出了一些示例。

视图 真实内容尺寸
UIView和NSView
Sliders 只定义了宽度(iOS)
Labels、buttons、switches和text fields 同时定义了宽度和高度
Text views 和 image views 不同情况下差别很大

intrinsic content size 基于视图的当前内容。一个label或button的 intrinsic content size 基于显示文字的总量和使用的字体。对于其他视图来说,intrinsic content size 可能会更复杂。例如,一个空的image view没有 intrinsic content size。一旦在上面添加图片之后,它的 intrinsic content size 就被设置为图片的尺寸了。

一个text view的 intrinsic content size 有多种不同情况,取决于其内容、是否可以滑动或者是给它添加的其他约束。比如,当可以滑动时,text view没有 intrinsic content size。当不可滑动时,默认来说视图的 intrinsic content size 基于不换行的文字计算而来。再例,在文字中如果不存在换行,intrinsic content size 会计算出需要的宽和高,并将内容布局为一个单行文字。如果你添加约束指定了text view的宽,intrinsic content size 就会根据此宽度来定义出需要的高度并进行显示。

Autolayout通过对每一个尺寸使用一对约束来表示真 intrinsic content size。抗拉伸约束(content hugging,内容包裹)把视图向内部推以保证它可以优雅地环抱着其内容。抗压缩约束(compression resistance)把视图向外推以便它不会轻易裁剪其内容。

image

在列表3-5中展示的这些约束通过使用不等式来进行定义。这里,IntrinsicHeightIntrinsicWidth常量代表了视图 intrinsic content size 中的宽和高。

// 抗压缩
View.height >= 0.0 * NotAnAttribute + IntrinsicHeight
View.width >= 0.0 * NotAnAttribute + IntrinsicWidth

// 抗拉伸
View.height <= 0.0 * NotAnAttribute + IntrinsicHeight
View.width <= 0.0 * NotAnAttribute + IntrinsicWidth

这些约束中的每一个都有自己的优先级。默认来说,视图使用250优先级来定义抗拉伸约束,而使用750优先级来定义抗压缩约束。因此,对于压缩视图来说,拉伸它更加容易。对大多数的控件来说,这都是默认行为。例如,你可以安全地将一个button拉伸到大于它本身的真实内容尺寸;但是,如果你压缩它,则很可能会裁剪其内容。记住,Interface Builder可能会适当修改这些优先级以避免此种情况发生。了解更多信息,请看设置抗拉伸和抗压缩约束的优先级

尽可能地在布局中多使用视图的 intrinsic content size。它可以让你的布局动态适配视图内容的变化。它还可以减少约束的数量来创建出明确的、无冲突的布局,但是你需要管理该视图的抗拉伸和抗压缩约束(统称为CHCR)的优先级。这里是一些处理 intrinsic content size 的指导建议:

上一篇 下一篇

猜你喜欢

热点阅读