虽然视觉化格式语言可以形象地描述大部分约束,但是,如果某个约束是根据另一个约束计算而来的,就无法使用视觉化格式语言。例如,假设需要将dateLabel的高度设置为nameLabel高度的两倍,就必须使用NSLayoutConstraint的另一个工厂方法:
+ (id)constraintWithItem:(id)view1
attribute:(NSLayoutAttribute)attr1
relatedBy:(NSLayoutRelation)relation
toItem:(id)view2
attribute:(NSLayoutAttribute)attr2
multiplier:(CGFloat)multiplier
constant:(CGFloat)c
与视觉化格式语言不同,该方法只会创建一个约束,该约束用于限定两个布局属性之间的关系。在该方法的参数中,multiplier是乘数,constant是常量,用于计算view1布局属性的值,稍后会给出计算表达式。
现在请读者打开NSLayoutConstraint头文件,找到NSLayoutAttribute枚举,其中包括所有布局属性常量:
•NSLayoutAttributeLeft
•NSLayoutAttributeRight
•NSLayoutAttributeTop
•NSLayoutAttributeBottom
•NSLayoutAttributeWidth
•NSLayoutAttributeHeight
•NSLayoutAttributeBaseline
•NSLayoutAttributeCenterX
•NSLayoutAttributeCenterY
•NSLayoutAttributeLeading
•NSLayoutAttributeTrailing
下面演示如何使用该方法:如果需要将imageView的宽度设置为自身高度的1.5倍,可以编写如下代码(读者不要将这段代码添加到项目中,否则会与其他约束产生冲突):
NSLayoutConstraint *aspectConstraint =
[NSLayoutConstraint constraintWithItem:self.imageView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self.imageView
attribute:NSLayoutAttributeHeight
multiplier:1.5
constant:0.0];
为了理解该方法所描述的约束,图16-4是该方法中各个参数的计算表达式,自动布局系统会根据该表达式为第一个参数所表示的视图计算布局属性的值,再创建相应的NSLayoutConstraint对象。
图16-4 NSLayoutConstraint表达式
由于该方法只创建了一个约束,因此需要使用UIView添加单个约束的实例方法:
- (void)addConstraint:(NSLayoutConstraint *)constraint
之前介绍过判断约束应该添加到哪个视图中的四条判定法则,而该方法符合第二条法则。该方法创建的约束只对第一个参数所表示的视图(这里是imageView)起作用,因此约束应该添加到该视图中。
对于aspectConstraint,应该将其添加到imageView中:
[self.imageView addConstraint:aspectConstraint];