首先讓我們了解一下什么是Autolayout
- Autolayout是一種“自動(dòng)布局”技術(shù),專門用來布局UI界面的
- Autolayout自iOS 6開始引入,由于Xcode 4的不給力,當(dāng)時(shí)并沒有得到很大推廣
- 自iOS 7(Xcode 5)開始,Autolayout的開發(fā)效率得到很大的提升
- 蘋果官方也推薦開發(fā)者盡量使用Autolayout來布局UI界面
- Autolayout能很輕松地解決屏幕適配的問題
(一)下面讓我們用例子來進(jìn)一步了解Autolayout
示例如下:

效果圖.png
代碼實(shí)現(xiàn)Autolayout的步驟
- 利用NSLayoutConstraint類創(chuàng)建具體的約束對(duì)象
- 添加約束對(duì)象到相應(yīng)的view上
- (void)addConstraint:(NSLayoutConstraint *)constraint;
- (void)addConstraints:(NSArray *)constraints;
代碼實(shí)現(xiàn)Autolayout的注意點(diǎn)
- 要先禁止autoresizing功能,設(shè)置view的下面屬性為NO
view.translatesAutoresizingMaskIntoConstraints = NO;
- 添加約束之前,一定要保證相關(guān)控件都已經(jīng)在各自的父控件上
- 不用再給view設(shè)置frame
創(chuàng)建約束對(duì)象的常用方法
創(chuàng)建約束對(duì)象的常用方法
+(id)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c;
view1 :要約束的控件
attr1 :約束的類型(做怎樣的約束)
relation :與參照控件之間的關(guān)系
view2 :參照的控件
attr2 :約束的類型(做怎樣的約束)
multiplier :乘數(shù)
c :常量
要用蘋果的方法代碼實(shí)現(xiàn)如下:(額,敲得我【惡心他媽給惡心開門----惡習(xí)到家了,不過不要擔(dān)心請(qǐng)接著往下看】)
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIView *blueView = [[UIView alloc] init];
blueView.backgroundColor = [UIColor blueColor];
// 禁止Autoresizing轉(zhuǎn)為Autolayout的約束
blueView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:blueView];
UIView *redView = [[UIView alloc] init];
redView.backgroundColor = [UIColor redColor];
// 禁止Autoresizing轉(zhuǎn)為Autolayout的約束
redView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:redView];
// 添加藍(lán)色控件的約束
NSLayoutConstraint *blueLeftLc = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0 constant:20];
[self.view addConstraint:blueLeftLc];
NSLayoutConstraint *blueBottomLc = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-20];
[self.view addConstraint:blueBottomLc];
NSLayoutConstraint *buleRightLc = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:redView attribute:NSLayoutAttributeLeft multiplier:1.0 constant:-20];
[self.view addConstraint:buleRightLc];
NSLayoutConstraint *blueHLc = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:40];
[self.view addConstraint:blueHLc];
NSLayoutConstraint *blueWidthLc = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:redView attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0];
[self.view addConstraint:blueWidthLc];
/*** 添加紅色控件的約束 ***/
NSLayoutConstraint *redTopLc = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0];
[self.view addConstraint:redTopLc];
NSLayoutConstraint *redBottomLc = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0];
[self.view addConstraint:redBottomLc];
NSLayoutConstraint *redRightLc = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1.0 constant:-20];
[self.view addConstraint:redRightLc];
}
@end
OK看到就這么一個(gè)簡單的效果要這么多代碼,是不是想要抓狂,不要心慌,下面我們介紹目前最流行的Autolayout第三方框架---Masonry
同樣的讓我們先大致了解一個(gè)Masonry的一些情況
目前最流行的Autolayout第三方框架
用優(yōu)雅的代碼方式編寫Autolayout
省去了蘋果官方惡心的Autolayout代碼
大大提高了開發(fā)效率
上面的效果圖用Masonry實(shí)現(xiàn)如下:
#import "ViewController.h"
//define this constant if you want to use Masonry without the 'mas_' prefix
#define MAS_SHORTHAND
//define this constant if you want to enable auto-boxing for default syntax
#define MAS_SHORTHAND_GLOBALS
#import "Masonry.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// 創(chuàng)建藍(lán)色View
UIView *blueView = [[UIView alloc] init];
blueView.backgroundColor = [UIColor blueColor];
[self.view addSubview:blueView];
// 創(chuàng)建紅色View
UIView *redView = [[UIView alloc] init];
redView.backgroundColor = [UIColor redColor];
[self.view addSubview:redView];
// 給藍(lán)色View添加約束
[blueView makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view.left).offset(20);
make.bottom.equalTo(self.view.bottom).offset(-20);
make.right.equalTo(redView.left).offset(-20);
make.height.equalTo(40);
make.width.equalTo(redView.width);
}];
// 給紅色View添加約束
[redView makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(self.view.right).offset(-20);
make.top.equalTo(blueView.top);
make.bottom.equalTo(blueView.bottom);
}];
// 更新約束
[blueView updateConstraints:^(MASConstraintMaker *make) {
make.height.equalTo(80);
}];
}
@end
上面這段代碼是不是讓你的心情大爽了呢,激動(dòng)之余細(xì)心的讀者可能發(fā)現(xiàn),咦#import "Masonry.h"上面怎么有兩個(gè)宏呢,下面我們來了解一下這是為什么呢
首先是Masonry中的mas_equalTo和equalTo
-
默認(rèn)情況下
- mas_equalTo有自動(dòng)包裝功能,比如自動(dòng)將20包裝為@20
- equalTo沒有自動(dòng)包裝功能
如果添加了下面的宏,那么mas_equalTo和equalTo就沒有區(qū)別
#define MAS_SHORTHAND_GLOBALS
// 注意:這個(gè)宏一定要添加到#import "Masonry.h"前面
其次是Masonry中的mas_width和width
-
默認(rèn)情況下
- width是make對(duì)象的一個(gè)屬性,用來添加寬度約束用的,表示對(duì)寬度進(jìn)行約束
- mas_width是一個(gè)屬性值,用來當(dāng)做equalTo的參數(shù),表示某個(gè)控件的寬度屬性
如果添加了下面的宏,mas_width也可以寫成width
#define MAS_SHORTHAND
mas_height、mas_centerX以此類推
總之這樣簡單高效的方法讓我們程序員用的好爽不是嗎
(二)開發(fā)中我們會(huì)遇到這樣的問題- 使用到約束的優(yōu)先級(jí)
- 為了大家更方便的學(xué)習(xí)我就不用代碼實(shí)現(xiàn)了,在Storyboard中添加約束
- 先看一下效果圖
// 點(diǎn)擊屏幕時(shí)會(huì)調(diào)用此方法
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//
[self.blueView removeFromSuperview];
// 利用2s的時(shí)間去更新約束,在修改了約束之后,只要執(zhí)行下面代碼,就能做動(dòng)畫效果,感興趣的讀者可以試一下
[UIView animateWithDuration:2 animations:^{
// 強(qiáng)制更新約束(讓self.view以及它的所有子控件都強(qiáng)制更新)
[self.view layoutIfNeeded];
}];
}

約束優(yōu)先級(jí).gif
OK這樣的效果怎么實(shí)現(xiàn)呢,給大家看兩張圖大家就明白約束優(yōu)先級(jí)的用處了
-
綠色與藍(lán)色的約束優(yōu)先級(jí)值
綠色與藍(lán)色的約束優(yōu)先級(jí)值.png - 綠色與紅色的約束優(yōu)先級(jí)值

綠色與紅色的約束優(yōu)先級(jí)值.png
- 從上面可以看出綠色與藍(lán)色的約束優(yōu)先級(jí)值大于綠色與紅色的約束優(yōu)先級(jí)值,所以當(dāng)3個(gè)View都存在時(shí)執(zhí)行綠色與藍(lán)色的約束優(yōu)先級(jí)值,
當(dāng)點(diǎn)擊屏幕,移除綠色View時(shí)綠色與藍(lán)色的約束優(yōu)先級(jí)值無效了,執(zhí)行綠色與紅色的約束優(yōu)先級(jí)值,故此可以實(shí)現(xiàn)以上效果
