继续Auto Layout - BNR篇。html
打开BNRDetailViewController.m文件,重载viewDidLoad方法来建立UIImageView对象。当你想要给经过加载NIB文件建立的视图层级添加约束时,须要重载viewDidLoad方法。以下:spa
1 - (void)viewDidLoad { 2 [super viewDidLoad]; 3 4 UIImageView *iv = [[UIImageView alloc] initWithImage:nil]; 5 iv.contentMode = UIViewContentModeScaleAspectFill; 6 iv.translatesAutoresizingMaskIntoConstraints = NO; 7 [self.view addSubview:iv]; 8 self.imageVeiw = iv; 9 }
每一个视图都有一个 translatesAutoresizingMaskIntoConstraints 属性,默认为YES,即iOS会自动建立一些约束来匹配视图自动调整。code
Apple推荐使用Visual Format Language(VFL)来程序化建立约束。orm
VFL:一种用字符串常量来描述约束的方式。htm
@"H:|-0-[imageView|-0-" ,其中H:指该约束是针对水平位置的。方括号内的imageView指要约束的视图。符号|表示视图的容器。此字符串表示:imageView离其容器左右边缘的距离为0点。同时,可简化为: @"H:|[imageView|" 对象
@"V:[dateLabel]-8-[imageView]-8-[tooBar]" ,其指imageView的顶部离dateLabel的距离为8点,imageView的底部离tooBar的距离为8点。可简化为: @"V:[dateLabel]-[imageView]-[tooBar]" blog
@"V:[someView(==50)]" ,指视图的高度约束为50点。ip
一个约束即NSLayoutConstraint类的对象,可将其添加到一个视图中。字符串
修改viewDidLoad方法,建立imageView水平和垂直方向的约束。以下:get
1 - (void)viewDidLoad { 2 [super viewDidLoad]; 3 4 UIImageView *iv = [[UIImageView alloc] initWithImage:nil]; 5 iv.contentMode = UIViewContentModeScaleAspectFill; 6 iv.translatesAutoresizingMaskIntoConstraints = NO; 7 [self.view addSubview:iv]; 8 self.imageVeiw = iv; 9 10 NSDictionary *nameMap = @{@"imageVeiw":self.imageVeiw, @"dateLabel":self.dateLabel, @"toolBar":self.toolBar}; 11 NSArray *horizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[imageVeiw]-0-|" 12 options:0 13 metrics:nil 14 views:nameMap]; 15 NSArray *verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[dateLabel]-[imageVeiw]-[toolBar]" 16 options:0 17 metrics:nil 18 views:nameMap]; 19 }
NSLayoutConstraint的类方法constraintsWithVisualFormat:options:metrics:views的第四个参数为:视觉格式化字符串中的名字与视图层级中的名字的映射。
添加约束的规则:
1)若是一个约束影响了两个具备相同父视图的view,则约束应添加到父视图中。
2)若是一个约束只影响到一个视图,该约束应添加到其所影响的视图中。
3)若是一个约束影响了两个不具备相同父视图的view,但共享一个ancestor,则该ancestor得到该约束。
4)若是一个约束影响一个视图和其父视图,则该约束添加到父视图中。
所以,在viewDidLoad方法中,将建立的约束添加到父视图中,添加以下粗体代码:
1 NSArray *verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[dateLabel]-[imageView]-[toolBar]" 2 options:0 3 metrics:nil 4 views:nameMap]; 5 [self.view addConstraints:horizontalConstraints]; 6 [self.view addConstraints:verticalConstraints];
Intrinsic Content Size:指一个视图的大小基于其要显示的内容。
contentCompressionResistancePriority 当其值小于1000时,Auto Layout可能压缩视图。
contentHuggingPriority 当其值小于1000时,Auto Layout可能增长视图的大小。
viewDidLoad方法添加代码以下:
1 ...... 2 self.imageVeiw = iv; 3 4 [self.imageVeiw setContentHuggingPriority:200 forAxis:UILayoutConstraintAxisVertical]; 5 [self.imageVeiw setContentCompressionResistancePriority:700 forAxis:UILayoutConstraintAxisVertical]; 6 ......
建立基于比率的约束时,不能使用VFL,此时须要用到NSLayoutConstraint类的 constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant: 类方法。其中multiplier属性是建立基于比率约束的关键。
1 NSLayoutConstraint *aspectConstraint = [NSLayoutConstraint constraintWithItem:self.imageVeiw 2 attribute:NSLayoutAttributeWidth 3 relatedBy:NSLayoutRelationEqual 4 toItem:self.imageVeiw 5 attribute:NSLayoutAttributeHeight 6 multiplier:1.5 7 constant:0.0];
添加的约束至关于 imageVeiw.width = 1.5 * imageVeiw.height + 0.0 。
autoresizing masks:约束一个视图和其父视图的关系,但不会影响同级视图间的关系。默认状况下,会基于autoresizing masks,给视图建立和添加约束。但其常常会与用程序代码添加的约束发生冲突。此时,只需将视图的 translatesAutoresizingMaskIntoConstraints 属性设为NO便可。