在Autolayout之前,有Autoresizing可以作屏幕適配枪汪,但局限性較大涌穆,有些任務根本無法完成。相比之下雀久,Autolayout的功能比Autoresizing強大很多宿稀。Autolayout自iOS 6開始引入。
Autolayout的2個核心概念
- 參照
- 約束
1赖捌、在storyboard和xib中使用AutoLayout約束面板添加約束
2祝沸、代碼添加約束
-
常規(guī)約束
代碼實現(xiàn)Autolayout的注意點
1.禁止將AutoresizingMask默認設置轉(zhuǎn)為約束
View.translatesAutoresizingMaskIntoConstraints = NO;
2.添加約束之前,一定要保證相關控件都已經(jīng)在各自的父控件上
3.不用再給view設置frame
一個NSLayoutConstraint對象就代表一個約束
創(chuàng)建約束對象的常用方法
/**
@param view1 要約束的控件
@param attr1 約束的類型
@param relation 與參照控制之間的關系
@param view2 參照的控件
@param attr2 約束的類型
@param multiplier 乘數(shù)
@param c 常量
*/
+(instancetype)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(nullable id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c;
自動布局的核心計算公式
obj1.property1 =(obj2.property2 * multiplier)+ constant value
添加約束的規(guī)則
- 對于兩個同層級view之間的約束關系,添加到它們的父view上
- 對于兩個不同層級view之間的約束關系罩锐,添加到他們最近的共同父view上
- 對于有層次關系的兩個view之間的約束關系奉狈,添加到層次較高的父view上
添加約束
- (void)addConstraint:(NSLayoutConstraint *)constraint NS_AVAILABLE_IOS(6_0);
- (void)addConstraints:(NSArray<__kindof NSLayoutConstraint *> *)constraints NS_AVAILABLE_IOS(6_0);
移除約束
- (void)removeConstraint:(NSLayoutConstraint *)constraint NS_AVAILABLE_IOS(6_0); // This method will be deprecated in a future release and should be avoided. Instead set NSLayoutConstraint's active property to NO.
- (void)removeConstraints:(NSArray<__kindof NSLayoutConstraint *> *)constraints NS_AVAILABLE_IOS(6_0); // This method will be deprecated in a future release and should be avoided. Instead use +[NSLayoutConstraint deactivateConstraints:].
刷新約束
- (void)layoutIfNeeded;
- (void)setNeedsUpdateConstraints NS_AVAILABLE_IOS(6_0);
示例
UIView *blueView = [UIView new];
blueView.backgroundColor = [UIColor blueColor];
[self.view addSubview:blueView];
// 禁止將AutoresizingMask默認設置轉(zhuǎn)為約束
blueView.translatesAutoresizingMaskIntoConstraints = NO;
UIView *redView = [UIView new];
redView.backgroundColor = [UIColor redColor];
[self.view addSubview:redView];
redView.translatesAutoresizingMaskIntoConstraints = NO;
// 藍色視圖
// 高度約束:100
NSLayoutConstraint *heightConstraint1 = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0.0 constant:100];
[blueView addConstraint:heightConstraint1];
// 左邊約束:20
NSLayoutConstraint *leftConstraint1 = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1.0 constant:20];
[blueView.superview addConstraint:leftConstraint1];
// 右邊約束:20
NSLayoutConstraint *rightConstraint1 = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:-20];
[self.view addConstraint:rightConstraint1];
// 頂部約束:20
NSLayoutConstraint *topConstraint1 = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:20];
[self.view addConstraint:topConstraint1];
// 紅色視圖
// 高度約束:同藍色一樣
NSLayoutConstraint *heightConstraint2 = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0];
[self.view addConstraint:heightConstraint2];
// 寬度約束:藍色一半
NSLayoutConstraint *widthConstraint2 = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeWidth multiplier:0.5 constant:0];
[self.view addConstraint:widthConstraint2];
// 頂部約束:距離藍色20
NSLayoutConstraint *topConstraint2 = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:20];
[self.view addConstraint:topConstraint2];
// 中心點約束
NSLayoutConstraint *centerXConstraint2 = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0];
[self.view addConstraint:centerXConstraint2];
-
可視化格式語言約束VFL(Visual format language)
添加方法
+ (NSArray<__kindof NSLayoutConstraint *> *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(nullable NSDictionary<NSString *,id> *)metrics views:(NSDictionary<NSString *, id> *)views;
一些用法示例
H:[cancelButton(72)]-12-[acceptButton(50)]
canelButton寬72,acceptButton寬50唯欣,它們之間間距12
H:[wideView(>=60@700)]
wideView寬度大于等于60point嘹吨,該約束條件優(yōu)先級為700(優(yōu)先級最大值為1000,優(yōu)先級越高的約束越先被滿足)
V:[redBox][yellowBox(==redBox)]
豎直方向上境氢,先有一個redBox蟀拷,其下方緊接一個高度等于redBox高度的yellowBox
H:|-10-[Find]-[FindNext]-[FindField(>=20)]-|
水平方向上,F(xiàn)ind距離父view左邊緣默認間隔寬度萍聊,之后是FindNext距離Find間隔默認寬度问芬;再之后是寬度不小于20的FindField,它和FindNext以及父view右邊緣的間距都是默認寬度寿桨。(豎線“|” 表示superview的邊緣)
示例
UIView *blueView = [UIView new];
blueView.backgroundColor = [UIColor blueColor];
[self.view addSubview:blueView];
// 禁止將AutoresizingMask默認設置轉(zhuǎn)為約束
blueView.translatesAutoresizingMaskIntoConstraints = NO;
UIView *redView = [UIView new];
redView.backgroundColor = [UIColor redColor];
[self.view addSubview:redView];
redView.translatesAutoresizingMaskIntoConstraints = NO;
// VFL實現(xiàn)AutoLayout
// 間距
NSNumber *margin = @20;
NSNumber *height = @30;
NSDictionary *views = NSDictionaryOfVariableBindings(blueView,redView);
NSDictionary *margins = NSDictionaryOfVariableBindings(margin,height);
// 添加水平方向約束
NSString *vfl_h = @"H:|-margin-[blueView]-margin-[redView(==blueView)]-margin-|";
NSArray *constraints_h = [NSLayoutConstraint constraintsWithVisualFormat:vfl_h options:kNilOptions metrics:margins views:views];
[self.view addConstraints:constraints_h];
// 添加垂直方向約束
NSString *vfl_v_b = @"V:|-20-[blueView(height)]";
NSArray *constraints_v_b = [NSLayoutConstraint constraintsWithVisualFormat:vfl_v_b options:kNilOptions metrics:margins views:views];
[self.view addConstraints:constraints_v_b];
NSString *vfl_v_r = @"V:|-20-[redView(height)]";
NSArray *constraints_v_r = [NSLayoutConstraint constraintsWithVisualFormat:vfl_v_r options:kNilOptions metrics:margins views:views];
[self.view addConstraints:constraints_v_r];