約束
:對控件位置和大小的限定條件參照
:對控件設置的約束是相對於哪個視圖而言的obj1.property1 =(obj2.property2 * multiplier)+ constant value
git
解釋:obj1的property1屬性等於obj2的property2屬性乘以multiplier(係數)再加constant(常量);github
約束的priority
屬性表示約束的優先級,取值區間爲[0,1000],默認爲1000。priority
值越大,表示優先級越高,會優先執行。優先級低的約束只有在優先級較高的約束失效後纔會執行。數組
在使用storyboard和xib設置約束時,約束有可能會變成黃色或者紅色。當發生這樣的狀況時,就說明設置的約束有問題。框架
代碼實現Autolayout須要注意:ide
NO
:view.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint
類建立具體的約束對象添加約束到相應的View上:佈局
- (void)addConstraint:(NSLayoutConstraint *)constraint; - (void)addConstraints:(NSArray *)constraints;
一個NSLayoutConstraint
對象就表明一個約束,能夠經過修改NSLayoutConstraint
對象的屬性來修改約束。動畫
建立約束對象經常使用的方法:ui
/** * 添加一個約束,其實就是根據公式來計算約束 * obj1.property1 =(obj2.property2 * multiplier)+ constant value * @param view1 須要添加約束的View * @param attr1 須要添加的約束(左邊、右邊、長寬仍是。。。) * @param relation 約束關係(大於、等於仍是小於) * @param view2 參照View(約束是相對於哪一個View而言) * @param attr2 參照View的哪個參數(左邊、右邊、長寬仍是。。。) * @param multiplier 係數 * @param c 常量值 * * @return 返回一個建立好的約束 */ + (instancetype)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(nullable id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c;
示例:spa
UIView *blueView = [[UIView alloc] init]; blueView.backgroundColor = [UIColor blueColor]; [self.view addSubview:blueView]; //關閉Autoresizing blueView.translatesAutoresizingMaskIntoConstraints = NO; //建立左邊約束 NSLayoutConstraint *leftLc = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0 constant:20]; [self.view addConstraint:leftLc]; //建立右邊約束 NSLayoutConstraint *rightLc = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1.0 constant:-20]; [self.view addConstraint:rightLc]; //建立底部約束 NSLayoutConstraint *bottomLc = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-20]; [self.view addConstraint:bottomLc]; //建立高度約束 NSLayoutConstraint *heightLc = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0.0 constant:50]; [blueView addConstraint: heightLc];
效果圖:
code
使用VFL來建立約束數組:
/** * 使用VFL語句來建立約束數組 * * @param format VFL語句 * @param opts 約束類型 * @param metrics VFL語句中用到的具體數值 * @param views VFL語句中用到的控件 * * @return 返回建立好的約束數組 */ + (NSArray<__kindof NSLayoutConstraint *> *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(nullable NSDictionary<NSString *,id> *)metrics views:(NSDictionary<NSString *, id> *)views;
VFL語句示例:
H:[cancelButton(72)]-12-[acceptButton(50)] canelButton寬72,acceptButton寬50,它們之間間距12 H:[wideView(>=60@700)] wideView寬度大於等於60point,該約束條件優先級爲700(優先級最大值爲1000,優先級越高的約束越先被知足) V:[redBox][yellowBox(==redBox)] 豎直方向上,先有一個redBox,其下方緊接一個高度等於redBox高度的yellowBox H:|-10-[Find]-[FindNext]-[FindField(>=20)]-| 水平方向上,Find距離父view左邊緣默認間隔寬度,以後是FindNext距離Find間隔默認寬度;再以後是寬度不小於20的FindField,它和FindNext以及父view右邊緣的間距都是默認寬度。(豎線「|」 表示superview的邊緣)
VFL代碼示例:
// 建立藍色View UIView *blueView = [[UIView alloc] init]; blueView.backgroundColor = [UIColor blueColor]; blueView.translatesAutoresizingMaskIntoConstraints = NO; [self.view addSubview:blueView]; // 建立紅色View UIView *redView = [[UIView alloc] init]; redView.backgroundColor = [UIColor redColor]; redView.translatesAutoresizingMaskIntoConstraints = NO; [self.view addSubview:redView]; // VFL建立約束 // 水平方向 NSString *VFL_H = @"H:|-space-[blueView]-space-[redView(==blueView)]-space-|"; NSDictionary *metrics = @{ @"space" : @30, }; // NSDictionary *views = @{ // @"blueView" : blueView, // @"redView" : redView // }; NSDictionary *views = NSDictionaryOfVariableBindings(blueView,redView); NSArray *arrayH = [NSLayoutConstraint constraintsWithVisualFormat:VFL_H options:NSLayoutFormatAlignAllTop metrics:metrics views:views]; [self.view addConstraints:arrayH]; // 垂直方向 NSString *VFL_V = @"V:[blueView(50)]-space-|"; NSArray *arrayV = [NSLayoutConstraint constraintsWithVisualFormat:VFL_V options:kNilOptions metrics:metrics views:views]; [self.view addConstraints:arrayV]; // 添加紅色View的約束 // 添加高度約束 NSLayoutConstraint *redV_height = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0]; [self.view addConstraint:redV_height];
效果圖:
Masonry是目前最流行的Autolayout第三方框架,讓你能夠用簡單的代碼來編寫Autolayout,省去了蘋果官方繁複的Autolayout代碼,大大提高了開發效率。
mas_equalTo
和equalTo
:默認狀況下mas_equalTo
有自動包裝功能,好比自動將20
包裝爲@20
。equalTo
沒有自動包裝功能。
若是添加了下面的宏,那麼mas_equalTo
和equalTo
就沒有區別:
#define MAS_SHORTHAND_GLOBALS // 注意:這個宏必定要添加到#import "Masonry.h"前面
mas_width
和width
:默認狀況下
width
是make
對象的一個屬性,用來添加寬度約束用的,表示對寬度進行約束。mas_width
是一個屬性值,用來當作equalTo
的參數,表示某個控件的寬度屬性。
若是添加了下面的宏,mas_width
也能夠寫成width
:
#define MAS_SHORTHAND
mas_height
、mas_centerX
以此類推。
下面用Masonry框架實現一下上面VFL語句的示例,對比一下就會發現有了Masonry框架之後自動佈局變得多麼容易:
//建立藍色控件 UIView *blueView = [[UIView alloc] init]; blueView.backgroundColor = [UIColor blueColor]; [self.view addSubview:blueView]; //建立紅色控件 UIView *redView = [[UIView alloc] init]; redView.backgroundColor = [UIColor redColor]; [self.view addSubview:redView]; // 添加blueView的約束 [blueView makeConstraints:^(MASConstraintMaker *make) { make.width.equalTo(redView.width).offset(0); make.height.equalTo(redView.height).offset(0); make.height.equalTo(100); make.left.equalTo(blueView.superview.left).offset(20); make.bottom.equalTo(blueView.superview.bottom).offset(-20); make.right.equalTo(redView.left).offset(-20); }]; // 添加redView的約束 [redView makeConstraints:^(MASConstraintMaker *make) { make.bottom.equalTo(redView.superview.bottom).offset(-20); make.right.equalTo(redView.superview.right).offset(-20); }];
Masonry框架提供了不少示例程序,感興趣的能夠打開上面GitHub的連接下載下來仔細研究,這裏就很少寫了。
GitHub連接爲:https://github.com/SnapKit/Masonry
在執行動畫時記得調用如下方法:
//在修改了約束以後,只要執行下面代碼,約束就能作出動畫效果 [UIView animateWithDuration:0.5 animations:^{ [self.view layoutIfNeeded]; }];
label.numberOfLines = 0;
,使label可以自動換行來計算高度preferredMaxLayoutWidth
。