生活随笔
收集整理的這篇文章主要介紹了
iOS8开发~UI布局(三)深入理解autolayout
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
一、概要
通過對(duì)iOS8界面布局的學(xué)習(xí)和總結(jié),發(fā)現(xiàn)autolayout才是主角,autolayout是iOS6引入的新特性,當(dāng)時(shí)還粗淺的學(xué)習(xí)了下,可是沒有真正應(yīng)用到項(xiàng)目中。隨著iOS設(shè)備尺寸逐漸碎片化,純粹的hard code方式UI布局將會(huì)走向死角,而autoresizing方式也有其局限性,所以無(wú)論如何autolayout都將成為UI布局的重要方式。
前兩篇以發(fā)燒友心態(tài)對(duì)iOS8界面布局的主要元素size class和autolayout進(jìn)行了探索,發(fā)現(xiàn)要完全掌握autolayout需要大量的時(shí)間去實(shí)踐總結(jié)。所以深入思考autolayout是很有必要的。你可能有和我同樣的疑問,如下:
1、以后一律使用autolayout嗎?除了在storyboard中使用autolayout,代碼方式autolayout如何使用?
2、好像忽略了一個(gè)重要問題,就是view動(dòng)畫在autolayout如何實(shí)現(xiàn)?
3、autolayout有沒有局限性和解決不了的問題?兼容性怎么樣?效率怎么樣?
4、……
二、研究開始
1、直接說以后都應(yīng)該使用storyboard+autolayout感覺是不負(fù)責(zé)的說法,讀了好多網(wǎng)絡(luò)的帖子,最后總結(jié)如下情況使用autolayout會(huì)有幫助:
a 當(dāng)需要展示的內(nèi)容很多并且尺寸不固定;
b 程序需支持屏幕旋轉(zhuǎn)(主要是iPad程序,iPhone程序橫屏的場(chǎng)景有點(diǎn)非主流);
c 程序通用于iPhone和iPad;
但storyboard中使用autolayout有利有弊,好處當(dāng)然是可視化,實(shí)現(xiàn)簡(jiǎn)單功能很節(jié)省時(shí)間,但也有弊端,例如不小心移動(dòng)一個(gè)控件就會(huì)讓弄亂那些約束。拋開storyboard而使用autolayout,就需要代碼定義約束了,而且代碼量也不是很大。當(dāng)app中一些view的出現(xiàn)時(shí)根據(jù)網(wǎng)絡(luò)數(shù)據(jù)來決定的時(shí)候,代碼方式可能更合適。
先看一個(gè)簡(jiǎn)單的Demo:
例子1:新建一個(gè)Single View Application template項(xiàng)目Demo4,在rootView上添加一個(gè)綠顏色的view,使新添加的view四個(gè)邊距離superView四邊20點(diǎn)寬
效果如圖:
使用storyboard來實(shí)現(xiàn)這個(gè)效果很簡(jiǎn)單,選中綠色view,然后添加4個(gè)相對(duì)于superview的邊界約束,約束的數(shù)值設(shè)置為20,然后Update Frame就可以了,因?yàn)椴粎^(qū)分iOS設(shè)備,所以size class可以設(shè)置為默認(rèn)的wAny hAny。Demo下載
接下來使用代碼來實(shí)現(xiàn)UI布局,目前有3種方法可以使用:(1)最基本的約束實(shí)現(xiàn)方式;(2)特殊格式化語(yǔ)言的約束實(shí)現(xiàn)方式;(3)第三方UIView-AutoLayout
(1)最基本的約束實(shí)現(xiàn)方式
[objc]?view plaincopy
<span?style="font-size:12px;">-?(void)viewDidLoad?{?? ????[super?viewDidLoad];?? ?????? ????self.view.translatesAutoresizingMaskIntoConstraints?=NO;?? ?????? ????UIView?*newView?=?[UIView?new];?? ????newView.backgroundColor?=?[UIColor?greenColor];?? ????[self.view?addSubview:newView];?? ?????? ????newView.translatesAutoresizingMaskIntoConstraints?=NO;?? ?????? ????NSLayoutConstraint?*constraint?=?nil;?? ?????? ????constraint?=?[NSLayoutConstraint?constraintWithItem:newView?? ??????????????????????????????????????????????attribute:NSLayoutAttributeLeading?? ??????????????????????????????????????????????relatedBy:NSLayoutRelationEqual?? ?????????????????????????????????????????????????toItem:self.view?? ??????????????????????????????????????????????attribute:NSLayoutAttributeLeading?? ?????????????????????????????????????????????multiplier:1.0f?? ???????????????????????????????????????????????constant:20];?? ????[self.view?addConstraint:constraint];?? ?????? ????constraint?=?[NSLayoutConstraint?constraintWithItem:newView?? ??????????????????????????????????????????????attribute:NSLayoutAttributeTrailing?? ??????????????????????????????????????????????relatedBy:NSLayoutRelationEqual?? ?????????????????????????????????????????????????toItem:self.view?? ??????????????????????????????????????????????attribute:NSLayoutAttributeTrailing?? ?????????????????????????????????????????????multiplier:1.0f?? ???????????????????????????????????????????????constant:-20];?? ????[self.view?addConstraint:constraint];?? ?????? ????constraint?=?[NSLayoutConstraint?constraintWithItem:newView?? ??????????????????????????????????????????????attribute:NSLayoutAttributeTop?? ??????????????????????????????????????????????relatedBy:NSLayoutRelationEqual?? ?????????????????????????????????????????????????toItem:self.view?? ??????????????????????????????????????????????attribute:NSLayoutAttributeTop?? ?????????????????????????????????????????????multiplier:1.0f?? ???????????????????????????????????????????????constant:20];?? ????[self.view?addConstraint:constraint];?? ?????? ????constraint?=?[NSLayoutConstraint?constraintWithItem:newView?? ??????????????????????????????????????????????attribute:NSLayoutAttributeBottom?? ??????????????????????????????????????????????relatedBy:NSLayoutRelationEqual?? ?????????????????????????????????????????????????toItem:self.view?? ??????????????????????????????????????????????attribute:NSLayoutAttributeBottom?? ?????????????????????????????????????????????multiplier:1.0f?? ???????????????????????????????????????????????constant:-20];?? ????[self.view?addConstraint:constraint];?? ?????? }</span>??
(2)特殊格式化語(yǔ)言的約束實(shí)現(xiàn)方式
[objc]?view plaincopy
<span?style="font-size:12px;">-?(void)viewDidLoad?{?? ????[super?viewDidLoad];?? ????self.view.translatesAutoresizingMaskIntoConstraints?=NO;?? ?????? ????UIView?*newView?=?[UIView?new];?? ????newView.backgroundColor?=?[UIColor?greenColor];?? ????[self.view?addSubview:newView];?? ????newView.translatesAutoresizingMaskIntoConstraints?=NO;?? ?????? ????NSMutableArray?*constraintArray?=?[NSMutableArray?array];?? ?????? ????[constraintArray?addObjectsFromArray:[NSLayoutConstraint?constraintsWithVisualFormat:@"H:|-20-[newView]-20-|"?? ?????????????????????????????????????????????????????????????????????????????????options:0?? ?????????????????????????????????????????????????????????????????????????????????metrics:nil?? ???????????????????????????????????????????????????????????????????????????????????views:NSDictionaryOfVariableBindings(newView,?self.view)]];?? ????[constraintArray?addObjectsFromArray:[NSLayoutConstraint?constraintsWithVisualFormat:@"V:|-20-[newView]-20-|"?? ?????????????????????????????????????????????????????????????????????????????????options:0?? ?????????????????????????????????????????????????????????????????????????????????metrics:nil?? ???????????????????????????????????????????????????????????????????????????????????views:NSDictionaryOfVariableBindings(newView,?self.view)]];?? ????[self.view?addConstraints:constraintArray];?? }</span>??
(3)第三方UIView-AutoLayout
[objc]?view plaincopy
<span?style="font-size:12px;">-?(void)viewDidLoad?{?? ????[super?viewDidLoad];?? ????self.view.translatesAutoresizingMaskIntoConstraints?=NO;?? ?????? ????UIView?*newView?=?[UIView?new];?? ????newView.backgroundColor?=?[UIColor?greenColor];?? ????[self.view?addSubview:newView];?? ????newView.translatesAutoresizingMaskIntoConstraints?=NO;?? ?????? ????[newView?autoPinEdgeToSuperviewEdge:ALEdgeLeading?withInset:20.0f];?? ????[newView?autoPinEdgeToSuperviewEdge:ALEdgeTrailing?withInset:20.0f];?? ????[newView?autoPinEdgeToSuperviewEdge:ALEdgeTop?withInset:20.0f];?? ????[newView?autoPinEdgeToSuperviewEdge:ALEdgeBottom?withInset:20.0f];?? }</span>??
以上3種方式都實(shí)現(xiàn)了我們想要的效果,看來代碼實(shí)現(xiàn)autolayout也不是那么復(fù)雜!
例子2:通過上邊例子我們實(shí)現(xiàn)一個(gè)簡(jiǎn)單的UI布局,下面來一個(gè)稍微復(fù)雜點(diǎn)的,把上一篇中提到3個(gè)view布局的那個(gè)例子用代碼布局實(shí)現(xiàn)一下,但難度有所增加,當(dāng)size class切換的時(shí)候,頁(yè)面布局發(fā)生相應(yīng)的改變,效果如圖:
? ? ? ? ? ??
首先初始化3個(gè)View:
[objc]?view plaincopy
<span?style="font-size:12px;">-?(UIView?*)?alView?{?? ????UIView?*newView?=?[UIView?new];?? ????newView.translatesAutoresizingMaskIntoConstraints?=NO;?? ?????? ????return?newView;?? }?? UIView?*greenView?=?[self?alView];?? greenView.backgroundColor?=?[UIColor?greenColor];?? [self.view?addSubview:greenView];?? UIView?*yellowView?=?[self?alView];?? yellowView.backgroundColor?=?[UIColor?yellowColor];?? [self.view?addSubview:yellowView];?? UIView?*blueView?=?[self?alView];?? blueView.backgroundColor?=?[UIColor?blueColor];?? [self.view?addSubview:blueView];</span>??
接下來適配豎屏的約束:
[objc]?view plaincopy
<span?style="font-size:12px;">-?(NSMutableArray?*)?portraitConstraints:(UIView?*)greenView?:(UIView?*)yellowView?:(UIView?*)blueView?? {?? ????NSMutableArray?*constraintArray?=?[NSMutableArray?array];?? ?????? ????[constraintArray?addObjectsFromArray:[NSLayoutConstraint?? ??????????????????????????????????????????constraintsWithVisualFormat:@"H:|-20-[greenView]-20-[yellowView(==greenView)]-20-|"?options:0?metrics:nil?? ??????????????????????????????????????????views:NSDictionaryOfVariableBindings(greenView,?yellowView)]];?? ????[constraintArray?addObjectsFromArray:[NSLayoutConstraint?? ??????????????????????????????????????????constraintsWithVisualFormat:@"V:|-20-[greenView]-20-[blueView(==greenView)]-20-|"?options:0?metrics:nil?? ??????????????????????????????????????????views:NSDictionaryOfVariableBindings(greenView,?blueView)]];?? ?????? ????[constraintArray?addObjectsFromArray:[NSLayoutConstraint?? ??????????????????????????????????????????constraintsWithVisualFormat:@"V:|-20-[yellowView]-20-[blueView(==yellowView)]-20-|"?options:0?metrics:nil?? ??????????????????????????????????????????views:NSDictionaryOfVariableBindings(yellowView,?blueView)]];?? ?????? ????[constraintArray?addObjectsFromArray:[NSLayoutConstraint?? ??????????????????????????????????????????constraintsWithVisualFormat:@"H:|-20-[blueView]-20-|"?options:0?metrics:nil?? ??????????????????????????????????????????views:NSDictionaryOfVariableBindings(blueView)]];?? ?????? ????return?constraintArray;?? }</span>??
然后橫屏的約束:
[objc]?view plaincopy
<span?style="font-size:12px;">-?(NSMutableArray?*)?landscapeConstraints:(UIView?*)greenView?:(UIView?*)yellowView?:(UIView?*)blueView?? {?? ????NSMutableArray?*constraintArray?=?[NSMutableArray?array];?? ?????? ????[constraintArray?addObjectsFromArray:[NSLayoutConstraint?? ??????????????????????????????????????????constraintsWithVisualFormat:@"H:|-20-[greenView]-20-[yellowView(==greenView)]-20-|"?options:0?metrics:nil?? ??????????????????????????????????????????views:NSDictionaryOfVariableBindings(greenView,?yellowView)]];?? ?????? ????[constraintArray?addObjectsFromArray:[NSLayoutConstraint?? ??????????????????????????????????????????constraintsWithVisualFormat:@"V:|-20-[blueView]-20-[greenView(==blueView)]-20-|"?options:0?metrics:nil?? ??????????????????????????????????????????views:NSDictionaryOfVariableBindings(greenView,?blueView)]];?? ?????? ????[constraintArray?addObjectsFromArray:[NSLayoutConstraint?? ??????????????????????????????????????????constraintsWithVisualFormat:@"V:|-20-[blueView]-20-[yellowView(==blueView)]-20-|"?options:0?metrics:nil?? ??????????????????????????????????????????views:NSDictionaryOfVariableBindings(yellowView,?blueView)]];?? ?????? ????[constraintArray?addObjectsFromArray:[NSLayoutConstraint?? ??????????????????????????????????????????constraintsWithVisualFormat:@"H:|-20-[blueView]-20-|"?options:0?metrics:nil?? ??????????????????????????????????????????views:NSDictionaryOfVariableBindings(blueView)]];?? ?????? ????return?constraintArray;?? }</span>??
最后還要處理屏幕旋轉(zhuǎn):
[objc]?view plaincopy
<span?style="font-size:12px;">-?(void)willTransitionToTraitCollection:(UITraitCollection?*)newCollection?? ??????????????withTransitionCoordinator:(id?<UIViewControllerTransitionCoordinator>)coordinator?? {?? ????[super?willTransitionToTraitCollection:newCollection?withTransitionCoordinator:coordinator];?? ?????? ????[coordinator?animateAlongsideTransition:^(id?<UIViewControllerTransitionCoordinatorContext>?context)?{?? ????????if?(newCollection.verticalSizeClass?==?UIUserInterfaceSizeClassCompact)?{?? ????????????NSLog(@"%s----%d",?__FUNCTION__,?__LINE__);?? ????????????[self.view?removeConstraints:self.view.constraints];?? ????????????[self.view?addConstraints:[self?landscapeConstraints:self.greenView_?:self.yellowView_?:self.blueView_]];?? ????????}?else?{?? ????????????NSLog(@"%s----%d",?__FUNCTION__,?__LINE__);?? ????????????[self.view?removeConstraints:self.view.constraints];?? ????????????[self.view?addConstraints:[self?portraitConstraints:self.greenView_?:self.yellowView_?:self.blueView_]];?? ????????}?? ????????[self.view?setNeedsLayout];?? ????}?completion:nil];?? }</span>??
這樣就實(shí)現(xiàn)了我們預(yù)期的效果,總結(jié)下來,auotlayout就是給view添加足夠的約束,讓view系統(tǒng)可以根據(jù)約束來計(jì)算出一個(gè)view的frame。動(dòng)手練習(xí)一下吧!
2、view動(dòng)畫在autolayout實(shí)現(xiàn)
當(dāng)布局發(fā)生改變時(shí),相當(dāng)于對(duì)子view進(jìn)行重新布局,而子view重新布局調(diào)用?layoutIfNeeded,所以動(dòng)畫可以這樣實(shí)現(xiàn):
[objc]?view plaincopy
<span?style="font-size:12px;">-?(void)animateConstraints?? {?? ????[UIView?animateWithDuration:0.5?animations:^{?? ????????[self.view?layoutIfNeeded];?? ????}];?? }</span>??
Github上已經(jīng)有Demo了!
3、autolayout有沒有局限性和解決不了的問題?兼容性怎么樣?效率怎么樣?
autolayout對(duì)view transforms支持的不好,這里有帖子詳細(xì)描述了這個(gè)問題。
至于兼容性,只從iOS6就已經(jīng)提出了autolayout的概念,現(xiàn)在iOS5系統(tǒng)不是很多了,甚至iOS6系統(tǒng)都已經(jīng)升級(jí)為iOS7,未來一段時(shí)間大部分用戶應(yīng)該是使用iOS7和iOS8系統(tǒng),所以兼容性問題不會(huì)太大,但size class是iOS8才有的概念,所以還有有一定的適配工作量。
效率話題這里有提到,有時(shí)間再細(xì)研究。
結(jié)束語(yǔ):時(shí)間和體力總是有限的,標(biāo)題是autolayout詳解,可想達(dá)到詳解還需要更多的時(shí)間去實(shí)踐和總結(jié),還有一些細(xì)節(jié)沒有體現(xiàn)出來:
例如:
[objc]?view plaincopy
<span?style="font-size:12px;">[NSLayoutConstraint?constraintsWithVisualFormat:@"H:|-20-[newView]-20-|"options:0?metrics:nil?views:NSDictionaryOfVariableBindings(newView,?self.view)]</span>?? 1、這其中各個(gè)參數(shù)的含義,另外約束還有個(gè)優(yōu)先級(jí)的概念
2、@"H:|-20-[newView]-20-|" 這種可視化布局字符串的含義等等,有空再補(bǔ)充了!
本篇內(nèi)容所有Demo
歡迎指出錯(cuò)誤,不勝感激。
總結(jié)
以上是生活随笔為你收集整理的iOS8开发~UI布局(三)深入理解autolayout的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。