亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

AutoLayout代碼布局使用大全—一種全新的布局思想

2019-11-14 18:18:21
字體:
來源:轉載
供稿:網友

相信ios8出來之后,不少的ios程序員為了屏幕的適配而煩惱。相信不少的人都知道有AutoLayout

這么個玩意可以做屏幕適配,事實上,AutoLayout不僅僅只是一個為了多屏幕適配的工具,

它真正的意義所在是給了程序員一種全新的布局思想。

   本文主要依據真實項目實例從三個方向全方位講解AutoLayout的使用大全。

   一。AutoLayout布局原理和語法

   二。約束沖突和AutoLayout動畫處理

   三。AutoLayout布局思想,約束鏈的控制。

   本文講解的內容和代碼主要依賴于一個名為UIView+AutoLayout的分類。文章末尾將會附上下載鏈接。

 

   一。AutoLayout布局原理和語法

     筆者在寫這篇文章之前,閱讀過不少關于AutoLayout教程的文章。其中有一句話尤為深刻,

學習AutoLayout之前,必須要完全拋棄傳統的frame屬性,先完成思想的扭轉學習起來方能事半功倍。

      AutoLayout是蘋果ios6出來的東西,與傳統的Frame屬性不同。每一個view對象都有一個frame屬性,

frame屬于CGrect對象,通過蘋果的Api可以得知,CGrect其實是一個結構體。

struct CGRect {

 CGPoint origin;

 CGSize size;

};

typedef struct CGRect CGRect;一個是控制坐標的CGPoint,一個是控制大小的CGSize。

 

   而AutoLayout是通過約束來實現布局的。一個view一旦使用了AutoLayout約束,

那么它的frame將永遠都是0.

   所以在使用AutoLayout之前需要兩個準備工作。

   1.設置

translatesAutoresizingMaskIntoConstraints為NO。

   2.如果是viewControl則AutoLayout適配寫在

- (void)updateViewConstraints中。

 如果是view則AutoLayout適配寫在

- (void)updateConstraints中。實際上,這也正是AutoLayout好處之一,可以集中將一個controller和

view的適配在一個方法中。

 

 

   AutoLayout語法主要分三類

    1.設置size。

    先來看看UIView+AutoLayout的實現。

 

[ViewautoSetDimension:ALDimensionWidthtoSize:30];

    UIView+AutoLayout底層原生的實現

 

 NSLayoutConstraint *constraint = [NSLayoutConstraintconstraintWithItem:selfattribute:NSLayoutAttributeWidth

 relatedBy:NSLayoutRelationEqual 

toItem:nilattribute:NSLayoutAttributeNotAnAttributemultiplier:0.0fconstant:size];

[View addConstraint:constraint];

    任何一個AutoLayout語法都是通過創建一個NSLayoutConstraint約束對象添加到view的約束中去的。

 

創建一個AutoLayout需要七個參數,他們分別是(1)WithItem:被約束對象  

(2)第一個attribute:被約束對象的關系   (3)relatedBy:約束描述  (

4)toItem:約束源   (5)第二個attribute:約束源的關系  (6)multiplier:約束系數 

 (7)constant:約束常數

    在官方的api中,對約束有一個計算公式

/* Create constraints explicitly.  Constraints are of the form "view1.attr1 = view2.attr2 * multiplier + constant" 

 

   下面具體講解參數在NSLayoutConstraint API中的對應屬性。

   

typedefNS_ENUM(NSInteger, NSLayoutAttribute) {

    NSLayoutAttributeLeft =1,

    NSLayoutAttributeRight,

    NSLayoutAttributeTop,

    NSLayoutAttributeBottom,

    NSLayoutAttributeLeading,

    NSLayoutAttributeTrailing,

    NSLayoutAttributeWidth,

    NSLayoutAttributeHeight,

    NSLayoutAttributeCenterX,

    NSLayoutAttributeCenterY,

    NSLayoutAttributeBaseline,

    NSLayoutAttributeLastBaseline =NSLayoutAttributeBaseline,

    NSLayoutAttributeFirstBaselineNS_ENUM_AVAILABLE_IOS(8_0),

    

    

    NSLayoutAttributeLeftMarginNS_ENUM_AVAILABLE_IOS(8_0),

    NSLayoutAttributeRightMarginNS_ENUM_AVAILABLE_IOS(8_0),

    NSLayoutAttributeTopMarginNS_ENUM_AVAILABLE_IOS(8_0),

    NSLayoutAttributeBottomMarginNS_ENUM_AVAILABLE_IOS(8_0),

    NSLayoutAttributeLeadingMarginNS_ENUM_AVAILABLE_IOS(8_0),

    NSLayoutAttributeTrailingMarginNS_ENUM_AVAILABLE_IOS(8_0),

    NSLayoutAttributeCenterXWithinMarginsNS_ENUM_AVAILABLE_IOS(8_0),

    NSLayoutAttributeCenterYWithinMarginsNS_ENUM_AVAILABLE_IOS(8_0),

    

    NSLayoutAttributeNotAnAttribute =0

};

 
 
以上是官方API對約束關系的描述,其中NSLayoutAttributeLeading,NSLayoutAttributeTrailing,實際上等同于left和right,據說是阿拉伯國家的使用習慣。
 可以根據以上枚舉看出約束關系主要就是上下左右,寬度,高度,橫坐標中心,縱坐標中心。
 
 

typedefNS_ENUM(NSInteger, NSLayoutRelation) {

    NSLayoutRelationLessThanOrEqual = -1,

    NSLayoutRelationEqual =0,

    NSLayoutRelationGreaterThanOrEqual =1,

};

  約束描述主要就是<= == >=  主要是用于不確定大小和坐標的約束,autolayout適配的靈活性和動態性主要來源于這個約束關系。
  約束系數multiplier和約束常數constant主要是計算約束關系最終結果的,遵循公式"view1.attr1 = view2.attr2 * multiplier + constant"
 
  以上就是所有布局的約束來源,可以看到使用起來非常的方便,由于要想準確的將一個View動態布局,
有時候往往需要設置好幾個約束來定位view的位置,所以這種代碼寫起來往往比設置frame更加的冗長,
好在文文介紹的UIView+AutoLayout可以替你分擔。
   
  回歸主題,通過以上代碼可以看到,由于只需要設置一個view的大小,所以不需要約束源,toItem
設為nil,那么約束源的關系自然就是沒有關系了,第二個Attribute設為NSLayoutAttributeNotAnAttribute。
   按照這種思維,其實我們就可以動態綁定一個view和另一個view的大小,實際上卻很少這么用,
為什么呢?之后會講到。
 
   2.位置間的約束
   先來看看UIView+AutoLayout的實現。
   [View1autoPinEdge:ALEdgeLefttoEdge:ALEdgeLeftofView:View1withOffset:5];
   UIView+AutoLayout底層原生的實現

NSLayoutConstraint *constraint = [NSLayoutConstraintconstraintWithItem:self

attribute:NSLayoutAttributeLeftrelatedBy:NSLayoutRelationEqual
toItem:View2attribute:NSLayoutAttributeLeftmultiplier:1.0fconstant:5];

[View1 addConstraint:constraint];

 

根據上文講解的各參數的含義可知,以上方法的意思就是約束view1的最左邊到view2的最左邊的距離是5(因為約束系數是1).

 

3.約束對齊

先來看看UIView+AutoLayout的實現。

 

[view1autoAlignAxisToSuperviewAxis:ALAxisVertical];

 UIView+AutoLayout底層原生的實現

   NSLayoutConstraint *constraint = [NSLayoutConstraintconstraintWithItem:selfattribute:NSLayoutAttributeCenterX 

relatedBy:NSLayoutRelationEqua toItem:view1.superview

attribute:NSLayoutAttributeCenterXmultiplier:1.0fconstant:0.0f];

根據上文講解的各參數的含義可知,以上方法的意思就是約束view1的橫坐標中心在view1的父view中居中.


因為前文說過,所有的約束都是創建一個相同的NSLayoutConstraint對象來實現。所以代碼都是大通小易。

 

以下主要講解一下UIView+AutoLayout這個分類的使用方法。

根據以上的約束三種用途,UIView+AutoLayout對應的方法主體上也分為三類。

1.設置size類(以autosetdimension開頭)


以下是ALDimension枚舉

 

typedefNS_ENUM(NSInteger,%20ALDimension)%20{

 %20 %20ALDimensionWidth%20=NSLayoutAttributeWidth, %20 %20 //%20the%20width%20of%20the%20view

 %20 %20ALDimensionHeight%20=NSLayoutAttributeHeight  %20 //%20the%20height%20of%20the%20view

};

 %202.位置約束(以autopin開頭)

以下是ALEdge枚舉

 

typedefNS_ENUM(NSInteger,%20ALEdge)%20{

 %20 %20ALEdgeLeft%20=NSLayoutAttributeLeft,%20 %20 %20 %20 %20 %20 //%20the%20left%20edge%20of%20the%20view

 %20 %20ALEdgeRight%20=NSLayoutAttributeRight,%20 %20 %20 %20 %20 //%20the%20right%20edge%20of%20the%20view

 %20 %20ALEdgeTop%20=NSLayoutAttributeTop,%20 %20 %20 %20 %20 %20 %20 //%20the%20top%20edge%20of%20the%20view

 %20 %20ALEdgeBottom%20= NSLayoutAttributeBottom,%20 %20 %20 %20 //%20the%20bottom%20edge%20of%20the%20view

 %20 %20ALEdgeLeading%20= NSLayoutAttributeLeading,%20 %20 %20 //%20the%20leading%20edge%20of%20the%20view%20(left%20edge%20for%20left-to-right%20languages%20like%20English,%20right%20edge%20for%20right-to-left%20languages%20like%20Arabic)

 %20 %20ALEdgeTrailing%20= NSLayoutAttributeTrailing %20 %20 //%20the%20trailing%20edge%20of%20the%20view%20(right%20edge%20for%20left-to-right%20languages%20like%20English,%20left%20edge%20for%20right-to-left%20languages%20like%20Arabic)

};

 

 %203.約束對齊(autoAlign開頭)

以下是ALAxis枚舉

 

typedefNS_ENUM(NSInteger, ALAxis) {

    ALAxisVertical = NSLayoutAttributeCenterX,     // a vertical line through the center of the view

    ALAxisHorizontal = NSLayoutAttributeCenterY,   // a horizontal line through the center of the view

    ALAxisBaseline = NSLayoutAttributeBaseline     // a horizontal line at the text baseline (not applicable to all views)

};

 

 

 

第一節小結:主要講解了一下AutoLayout底層實現原理和UIView+AutoLayout的封裝原理。


 二。AutoLayout約束沖突和動畫處理



 以上的這個頁面就是完全用的AutoLayout布局,整體結構就是這樣,頂部的label1和右上角按鈕button1,

中間的imageview1和label2,下方兩個cellview1和cellview2,再下面一個button2,

最下面的小提示忽略不計。

cellview1和cellview2是自定義的view,里面的一些image view和label都是它的子view。

重點:當一個父view1有了一個子view2,并且子view2有了子view3,那么在約束view3的時候,

如果它的父view不是最高層的那個view,那么view3的約束會對它的父view產生約束影響。  

這一個規則確實讓人很難摸清頭腦,筆者這里不再詳細說明,希望讀者在遇到約束沖突的時候

逐漸摸清這個規則。

 

AutoLayout的動畫處理。

假如一個view使用了AutoLayout約束布局之后,這個時候如果對這個view做一個動畫處理,

按照傳統的做法是改變它的一些屬性,在平移動畫中主要是改變它的frame坐標,

但是在AutoLayout中frame都是0應該如何處理呢。這里筆者由難到易提供三種解決方案。

1.使用[self.viewlayoutIfNeeded]方法動態刷新約束,筆者認為這個對初學AutoLayout的人

來說是最難的。

2.改變view的bounds屬性。這個網上有資料,在AutoLayout中bounds屬性是有效的。

這個可能相對好解決一點。

3.改變view的transform屬性,比如說網上平移10個距離,可以這樣寫self.transform = CGAffineTransformMakeTranslation(0, -10); 相信這個是最簡單也是最好處理的了。

 

 三。AutoLayout布局思想,約束鏈的控制

  

 還是使用這個頁面加上UIView+AutoLayout來詳細講解。

   比如說我要布局cellView1中最左邊那個招商銀行logo的imageview。

   使用UIView+AutoLayout可以這樣寫。

 

[imageview autoPinEdge:ALEdgeTop toEdge:ALEdgeTop ofView:self withOffset:5];

[imageview autoPinEdge:ALEdgeLeft toEdge:ALEdgeLeft ofView:self withOffset:5];

[imageview autoPinEdge:ALEdgeBottom toEdge:ALEdgeBottom ofView:self withOffset:5];

[imageview autoPinEdge:ALEdgeRight toEdge:ALEdgeLeft ofView:self withOffset:35];

   基本上任何的view都可以分別對它的上下左右使用四個位置約束來確定它的位置,

這四行代碼的意思本別就是

   imageview頂部距離父view頂部間距5,image view底部距離父view底部間距5,

imageview左側距離父view左側間距5,imageview右側距離父view左側間距35,

    這樣子的話,假如父view的高度是40的話,那么imageview的size不需要設置,

自然而然的被這四個約束為(30,30).

    這看起來沒什么不妥,實際上已經是約束過度了。當父view的高度發生變更的時候,

imageview的高度就會因為頂部和底部的約束而動態計算,假如父view高50,

那么imageview的size就是(30,40),這個時候假如是一張方形圖片就會變形,

實際上這并不是AutoLayout的精髓。

   

    再看下面這種約束方式

    

 [ImageViewautoSetDimensionsToSize:CGSizeMake(30,30)];

 [ImageViewautoPinEdge:ALEdgeLefttoEdge:ALEdgeLeftofView:selfwithOffset:5];

 

 [ImageViewautoAlignAxisToSuperviewAxis:ALAxisHorizontal];

    這三行代碼的意思是,約束imageview的固定大小(30,30),

約束imageview左側距離父view左側間距為5,約束imageview的縱坐標軸線與父view縱坐標軸線對齊。

通過以上三個約束不難看出,無論父view如果改變大小和位置,

image自身的形狀和父view的相對位置都是固定的。

   

    總結:AutoLayout真正的語法只有一個方法,只要理解這個方法的七個參數分別所代表的含義就不難理解AutoLayout的實現原理。所以對于程序員來說,重要的并不是這種布局方式用代碼寫起來有多么的冗長,因為有不少的三方庫可以幫助你簡寫代碼,實際上我們真正要掌握的是AutoLayout的這種布局思想,心中對一個view布局的時候心中都應該要有一條約束鏈,只有這樣,你的布局約束將會越來越精簡,越來越準確,也越來越適配。

 

   因為筆者自己也是剛剛接觸AutoLayout,以上只是粗略的講解一下自身的學習心得,筆者極力推薦UIView+AutoLayout這個庫來使用AutoLayout,因為封裝都比較形象,并且接近底層,對理解AutoLayout的原理和掌握內涵更加的有益。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久精品2019中文字幕| 亚洲日韩欧美视频| 国产激情久久久久| 亚洲а∨天堂久久精品喷水| 黑人精品xxx一区| 亚洲一区二区免费在线| 国产一区二区三区四区福利| 国产欧亚日韩视频| 最近更新的2019中文字幕| 国产99在线|中文| 亚洲丁香婷深爱综合| 日韩在线中文字幕| 亚洲精品免费一区二区三区| 91av视频在线播放| 亚洲伊人久久大香线蕉av| 亚洲人成电影网站| 国产一区二区三区18| 中文欧美日本在线资源| 亚洲综合大片69999| 欧美大片在线免费观看| 91精品久久久久久久| 2020国产精品视频| 久久久久日韩精品久久久男男| 91精品国产99| 亚洲最大成人免费视频| 久久精品99国产精品酒店日本| 伊人青青综合网站| 伊人亚洲福利一区二区三区| 久久这里有精品| 亚洲精品一区久久久久久| 日韩电影免费在线观看| 国产精品女主播视频| 久久躁狠狠躁夜夜爽| 成人av色在线观看| 欧美性色视频在线| 亚洲高清免费观看高清完整版| 欧美一区二区三区艳史| 久久精品国产91精品亚洲| 国精产品一区一区三区有限在线| 久久精视频免费在线久久完整在线看| 91精品国产综合久久香蕉最新版| 7777精品久久久久久| 亚洲曰本av电影| 欧美一级大胆视频| 久久久精品999| 欧美精品videossex性护士| 日韩精品在线观看网站| 欧美韩国理论所午夜片917电影| 亚洲福利在线观看| 欧美另类极品videosbestfree| 九九热在线精品视频| 国产成人精品日本亚洲| 日韩欧美国产免费播放| 久久精品视频在线| 久久人91精品久久久久久不卡| 国产精品久久久久久av下载红粉| 精品av在线播放| 精品福利一区二区| 国产精品久久久久久久久久久久久久| 最近2019好看的中文字幕免费| 啊v视频在线一区二区三区| 亚洲free性xxxx护士白浆| 国产高清视频一区三区| 国产精品日日做人人爱| 亚洲综合日韩中文字幕v在线| 久久久久久国产精品三级玉女聊斋| 亚洲国产精品va在线观看黑人| 色偷偷9999www| 亚洲tv在线观看| 中文字幕久久久| 伊人久久综合97精品| 91精品国产91久久久久久久久| 国产91精品青草社区| 日韩精品在线播放| 正在播放国产一区| 久久久久久一区二区三区| 成人久久久久久久| 55夜色66夜色国产精品视频| 亚洲精品视频免费| 97福利一区二区| 亚洲成色777777女色窝| 亚洲深夜福利网站| 亚洲xxx自由成熟| 国产成人一区三区| 日韩欧美国产视频| 精品小视频在线| 91亚洲国产成人久久精品网站| 亚洲欧美综合图区| 久久夜精品va视频免费观看| 日韩专区在线播放| 奇米影视亚洲狠狠色| 中文日韩电影网站| 欧美xxxx做受欧美| 欧美激情一区二区三区高清视频| 亚洲第一av网| 亚洲国产欧美自拍| 欧美激情2020午夜免费观看| 日本精品视频在线| 国产午夜精品视频| 欧美激情精品久久久久久变态| 国产日韩欧美日韩| 这里只有精品在线播放| 538国产精品视频一区二区| 欧美色另类天堂2015| 蜜臀久久99精品久久久久久宅男| 欧美日韩国产精品一区二区不卡中文| 狠狠久久五月精品中文字幕| 91性高湖久久久久久久久_久久99| 欧美激情一区二区三级高清视频| 在线亚洲男人天堂| 久色乳综合思思在线视频| 亚洲激情视频在线观看| 国产精品视频99| 国产精品青青在线观看爽香蕉| 欧美国产精品人人做人人爱| 亚洲在线免费视频| 国产精品网红福利| 亚洲男人天堂2024| 狠狠色香婷婷久久亚洲精品| 欧美日韩国产中文字幕| 91在线视频九色| 92国产精品久久久久首页| 久久人人97超碰精品888| 国产精品视频久| 亚洲福利小视频| 伊人一区二区三区久久精品| 国产精选久久久久久| 国产成人精品电影| 5252色成人免费视频| 国产乱肥老妇国产一区二| 96sao精品视频在线观看| 成人网中文字幕| 尤物tv国产一区| 福利二区91精品bt7086| 国产精品爽爽爽| 亚洲欧美日韩直播| 欧美片一区二区三区| 日本人成精品视频在线| 国产精品美女久久久久av超清| 日韩视频在线一区| 韩国国内大量揄拍精品视频| 欧美麻豆久久久久久中文| 欧美在线视频免费播放| 亚洲iv一区二区三区| 国产成人综合精品在线| 欧美性猛交xxxx乱大交3| 中文字幕亚洲激情| 97精品国产91久久久久久| 不卡av日日日| 日韩最新在线视频| 精品国产欧美一区二区三区成人| 亚洲自拍小视频免费观看| 国产丝袜一区二区三区免费视频| 色播久久人人爽人人爽人人片视av| 欧美肥婆姓交大片| 国产午夜一区二区| 亚洲国产精品成人av| 亚洲肉体裸体xxxx137| 69久久夜色精品国产69乱青草| 日本在线观看天堂男亚洲| 国产日韩欧美夫妻视频在线观看| 中日韩美女免费视频网站在线观看| 成人黄色片网站| 毛片精品免费在线观看|