iOS6 之後,蘋果公司引進了Auto Layout,相比之前的autoresizing功能更強大,這也是蘋果公司為了未來不同機型未雨綢缪的措施。
這裡要注意幾點:
- 對子視圖的限制,若是基于父視圖,要通過父視圖去添加限制。
- 對子視圖進行自動布局調整,首先對UIView的一個屬性設定,這是因為如果我們用Interface Builder,勾選Ues Autolayout,這時autoresizingMask就會被Auto Layout 取代,在手寫代碼時,我們就需要手動控制,代碼如下
[_shadow setTranslatesAutoresizingMaskIntoConstraints:NO]
-
在添加限制前,要先将子視圖添加到父視圖上。
以下為例,oneImgView 上添加子視圖shadow,對shadow進行限制
@property (nonatomic, strong) UIImageView *shadow;
@property (nonatomic, strong) UIImageView *oneImgView;
[_shadow setTranslatesAutoresizingMaskIntoConstraints:NO]; // 使用自動布局
[self.oneImgView addSubview:_shadow]; // 添加限制前要先将子視圖添加到父視圖上
NSLayoutConstraint *constraint = [NSLayoutConstraint
constraintWithItem:_shadow
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self.oneImgView
attribute:NSLayoutAttributeWidth
multiplier:
constant:];
[self.oneImgView addConstraint:constraint];
constraint = [
NSLayoutConstraint
constraintWithItem:_shadow
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:self.oneImgView
attribute:NSLayoutAttributeBottom
multiplier:f
constant:f
];
[self.oneImgView addConstraint:constraint];
constraint = [
NSLayoutConstraint
constraintWithItem:_shadow
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeHeight
multiplier:f
constant:f
];
[self.oneImgView addConstraint:constraint];
constraint = [
NSLayoutConstraint
constraintWithItem:_shadow
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual
toItem:self.oneImgView
attribute:NSLayoutAttributeLeft
multiplier:f
constant:f
];
[self.oneImgView addConstraint:constraint];
關于函數
+(instancetype)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c;
蘋果的官方文檔是這麼描述的。
/* Create constraints explicitly. Constraints are of the form "view1.attr1 = view2.attr2 * multiplier + constant"
If your equation does not have a second view and attribute, use nil and NSLayoutAttributeNotAnAttribute.
*/
是以你隻需要記住view1.attr1 = view2.attr2 * multiplier + constant就可以了
可視化格式語言限制(VFL)
除此之外iOS 8推出了一種新的限制方式——可視化格式語言限制,這種限制方式和中國古代的象形文字很相似。它可以一次添加多個限制,而且很直覺,但不是所有的限制都可以滿足的,維護也有一定的難度
代碼為例,如果我要實作shadow 距離父視圖左邊界為20,寬為40,距離頂部20,高度最小30,不能超過100
NSArray *constraints = nil;
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-20-[_shadow(==40)]|" options:NSLayoutFormatAlignAllLeft metrics:nil views:NSDictionaryOfVariableBindings(_shadow)];
[self.oneImgView addConstraints:constraints];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[_shadow(>=58)@100]" options:NSLayoutFormatAlignAllLeft metrics:nil views:NSDictionaryOfVariableBindings(_shadow)];
[self.oneImgView addConstraints:constraints];
- format:這裡是你的VFL語句,比如:@”H:|[_shadow]|”(注意“-”預設父子視圖之間表示20px,同級視圖之間表示8px,但是如果是“-10-”則表示前後相距10,短線距離忽略)
- options:預設寫0,跟據需求去選擇你想要的枚舉
- metrics:字典, 你的VFL語句中使用了動态參數時,将參數名和對應的值為鍵值對寫在字典中,比如:@”H:|-[_shadow(==width)]-|”,表示這個_shadow的寬度為width,這是字典裡面找到key對就的值,如果沒有找到這個值,app就會crash.
-
views:字典,你的VLF語句中使用到得所有view,用這個宏去添加NSDictionaryOfVariableBindings(view1,view2,view3…)
上面代碼中VFL語句為:@”H:|[_shadow]|”,其中“|”表示父視圖的邊界
以下為VLF語句
|: 表示父視圖
-:表示距離
V: :表示垂直
H: :表示水準
>= :表示視圖間距、寬度和高度必須大于或等于某個值
<= :表示視圖間距、寬度和高度必須小宇或等于某個值
== :表示視圖間距、寬度或者高度必須等于某個值
@ :>=、<=、== 限制 最大為 1000
以下為例
|-[view]-|: 視圖處在父視圖的左右邊緣内
|-[view] : 視圖處在父視圖的左邊緣
|[view] : 視圖和父視圖左邊對齊
-[view]- : 設定視圖的寬度高度
|-30.0-[view]-30.0-|: 表示離父視圖 左右間距 30
[view(200.0)] : 表示視圖寬度為 200.0
|-[view(view1)]-[view1]-| :表示視圖寬度一樣,并且在父視圖左右邊緣内
V:|-[view(50.0)] : 視圖高度為 50
V:|-(==padding)-[imageView]->=0-[button]-(==padding)-| : 表示到父視圖左邊的距離為Padding,這兩個視圖間距必須大于或等于0并且距離底部父視圖為 padding。
[wideView(>[email protected])] :視圖的寬度為至少為60 不能超過 700
如果沒有聲明方向預設為 水準 V: