之前說(shuō)到自動(dòng)布局的關(guān)鍵就是給出正確且完整的約束。那么看一下下面的例子給出的例子約束是否完整:
(這里使用Masonry來(lái)描述約束,可以參考https://github.com/SnapKit/Masonry,但是我覺(jué)得直接看也能夠看得懂了)
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);
}];
這里只定義了兩個(gè)約束颂碧,left 和 top,只夠計(jì)算出frame的originX和orginY,沒(méi)有width和height软驰。那么是不是屬于不完整的約束呢?其實(shí)在這里給出的約束已經(jīng)是完整的了心肪。因?yàn)閷?duì)于UILabel這個(gè)控件而言 锭亏,只要通過(guò)其font和text系統(tǒng)就可以計(jì)算出Label該有的長(zhǎng)度和寬度。這里的長(zhǎng)度和寬度就是UILabel的intrinsic content size(固有屬性)硬鞍。
官方文檔給出的視圖與intrinsic content size:
View | Intrinsic content size |
---|---|
UIView and NSView | No intrinsic content size. |
Sliders | Defines only the width |
Labels, buttons, switches, and text fields | Defines both the height and the width. |
Text views and image views | Intrinsic content size can vary. |
那么對(duì)于具有intrinsic content size的視圖來(lái)說(shuō)慧瘤,是不是意味著自動(dòng)幫該這些視圖添加了像width=a,height=b這樣的約束呢固该?
這里锅减,其實(shí)在布局的時(shí)候會(huì)添加四個(gè)約束(對(duì)于height 和 width均有intrinsic size的情況下):
// Compression Resistance
View.height >= IntrinsicHeight
View.width >= IntrinsicWidth
// Content Hugging
View.height <= IntrinsicHeight
View.width <= IntrinsicWidth
compression resistance
2,3為抗壓縮約束伐坏,防止視圖被壓縮怔匣,約束默認(rèn)的優(yōu)先級(jí)為750(UILayoutPriorityDefaultHigh)。設(shè)置的API為:
- (void)setContentCompressionResistancePriority:(UILayoutPriority)priority forAxis:(UILayoutConstraintAxis)axis
axis參數(shù)表示方向桦沉,水平或者垂直每瞒。
content hugging
6,7約束防止視圖被拉伸纯露,約束的默認(rèn)優(yōu)先級(jí)為250(UILayoutPriorityDefaultLow)剿骨。設(shè)置的API為:
- (void)setContentHuggingPriority:(UILayoutPriority)priority forAxis:(UILayoutConstraintAxis)axis
應(yīng)用
一般我們會(huì)如何運(yùn)用compression resistance 和 content hugging呢?
給出一個(gè)比較常見(jiàn)的需求:
在同一行中顯示標(biāo)題和時(shí)間埠褪,時(shí)間必須顯示完全浓利,標(biāo)題如果太長(zhǎng)就截取可顯示的部分挤庇,剩余的用…表示。
代碼如下:
UILabel *titleLabel = [[UILabel alloc] init];
[self.view addSubview:titleLabel];
titleLabel.text = @"Each of these constraints can have its own priority. By default, ";
[titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view.mas_left).offset(16);
make.top.equalTo(self.view.mas_top).offset(100);
}];
UILabel *timeLabel = [[UILabel alloc] init];
timeLabel.text = @"2017/03/12 18:20:22";
[self.view addSubview:timeLabel];
[timeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(titleLabel.mas_right).offset(8);
make.top.equalTo(titleLabel.mas_top);
make.right.lessThanOrEqualTo(self.view.mas_right).offset(-8);
}];
// [timeLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
最后一句被注釋的結(jié)果:
去掉注釋后的結(jié)果:
這是因?yàn)槿サ糇⑨尯筌癖欤瑃imeLabel的水平抗壓縮約束的優(yōu)先級(jí)(required罚随,1000)高于titleLabel的優(yōu)先級(jí)(750)。所以這里被壓縮的是titleLabel羽资。同理也可應(yīng)用于content hugging淘菩,只是將方向方向改變一下。