固有内容大小的含义:视图要显示的实际内容区域大小。例如,UILabel的固有内容大小是由需要显示的文字数量决定的。而UIImageView的固有内容大小则是所显示图片的尺寸。
自动布局系统会根据固有内容大小为视图添加相应的约束,与其他约束不同,这类约束有两个优先级属性,分别是内容放大优先级(content hugging priority)和内容缩小优先级(content compression resistance priority)。
优先级属性在水平方向和垂直方向可以有不同的数值。因此,可以为视图的宽和高设置不同的优先级,每个视图都有四个优先级数值。
首先介绍如何在Interface Builder中查看并修改这些优先级。重新打开BNRDetailView- Controller.xib,按住Shift,在画布中同时选中三个UITextField对象。然后点击图标,打开大小检视面板(size inspector),找到Content Hugging Priority和Content Compression Resistance Priority部分(见图16-3)。
图16-3 在Interface Builder中查看优先级
可以看见,目前这些优先级的数值并不是1000,其中Content Hugging Priority的Vertical是250,而imageView的是251。因此,如果用户选择了一张小尺寸图片,自动布局系统会增加UITextField对象的高度,使高度超出UITextField对象的固有内容大小。为了解决该问题,需要将imageView垂直方向的优先级设置为比其他视图低的数值。
下面介绍如何通过代码修改视图的优先级属性。打开BNRDetailViewController.m,修改viewDidLoad方法,降低imageView垂直方向的优先级,代码如下:
- (void)viewDidLoad
{
[super viewDidLoad];
UIImageView *iv = [[UIImageView alloc] initWithImage:nil];
// 设置UIImageView对象的内容缩放模式
iv.contentMode = UIViewContentModeScaleAspectFit;
// 告诉自动布局系统不要将自动缩放掩码转换为约束
iv.translatesAutoresizingMaskIntoConstraints = NO;
// 将UIImageView对象添加到view上
[self.view addSubview:iv];
// 将UIImageView对象赋给imageView属性
self.imageView = iv;
// 将imageView垂直方向的优先级设置为比其他视图低的数值
[self.imageView setContentHuggingPriority:200
forAxis:UILayoutConstraintAxisVertical];
[self.imageView setContentCompressionResistancePriority:700
forAxis:UILayoutConstraintAxisVertical];
}
构建并运行应用,选择一张小尺寸图片,这次自动布局系统不会再修改UITextField对象的高度。