Auto layout 的使用

什麼是Auto Layout

Auto Layout,是蘋果公司提供的一個基於約束佈局,動態計算大小和位置的庫,而且已經集成到了Xcode開發環境裏裏。ide

在引入Auto Layout以前,都是採用手動佈局的方式。手動佈局的方式原始落後,界面開發維護效率低,爲了提升更好得界面引擎給開發這體驗,隨之引入Auto Layout。工具

來歷

Cassowary是個解析工具包,可以有效解析線性等式系統和線性不等式系統,用戶的界面中老是會出現不等關係和相等關係,Cassowary開發了一種規則系統能夠經過約束來描述視圖間關係。約束就是規則,可以表示出一個視圖相對於另外一個視圖的位置。oop

Auto Layout生命週期

Auto Layout 用一整套佈局引擎管理佈局的建立,更新,銷燬。這一整套佈局引擎系統叫作Layout Engine,是Auto Layout的核心,主導着整個佈局頁面。佈局

每一個視圖在獲得本身的佈局以前,Layout engine會將視圖,約束,優先級,固定大小計算經過轉換成最終的大小和位置。在Layout engine裏,會有約束變化到Deferred Layout Pass 再到應用Runloop 在回到約束變化這樣的循環機制。以下圖所示:flex

約束變化

觸發約束變化包括:code

  • Activating 或 Deactivating
  • 設置constant 或 priority
  • 添加和刪除時圖

這個Engine遇到約束變化會從新計算layout,獲取新值後會call它的superview.setNeedslayout()orm

Deferred Layuot Pass

在這個時候主要是作些容錯處理,更新約束有些沒有肯定或者缺失佈局聲明的視圖會在這裏處理。接着從上而下調用layoutSubviews()來肯定視圖各個子視圖的位置,這個過程實際上就是將subview的frame從layout engine裏拷貝出來。這裏要注意重寫layoutSubviews()或者執行相似layoutIfNeeded這樣可能會馬上喚起layoutSubviews()的方法,若是要這樣作須要注意手動處理的這個地方本身的子視圖佈局的樹狀關係是否合理。cdn

生命週期中須要注意的事項

  • 不要指望frame會馬上變化
  • 在重寫layoutSubviews()時須要很是當心

使用API約束

[NSLayoutContraint constraintWithItem:view1 attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:view2 attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-5]blog

使用VFL語言約束

[NSLayoutConstraint constraintWithVisualFormat:@「[view1]-[view2]" options:0 metrics:nil views:viewsDictionary;生命週期

VFL幾個例子

  • [view1(50)]-10-[view2(100)] 表示view1寬50,view2寬100,間隔10
  • [view1(>=50@750)] 表示view1寬度大於50,約束條件優先級爲750(優先級越大優先執行該約束,最大1000)
  • V:[view1][view2(==view1)] 表示按照豎直排,上面是view1下面是一個和它同樣大的view2
  • H:|-[view1]-[view2]-[view3(>=20)]-| 表示按照水平排列,|表示父視圖,各個視圖之間按照默認寬度來排列

VFL的語法

  1. 標準間隔:[button]-[textField]
  2. 寬約束: [button(>=50)]
  3. 與父視圖的關係: |-50-[purpleBox]-50-|
  4. 垂直佈局: V:[topField]-10-[bottomField]
  5. Flush Views:[maroonView][buleView]
  6. 權重:[button(100@20)]
  7. 等寬:[button(==button2)]
  8. Multiple Predicates: [flexibleButton(>=70,<=100)]

注意事項

  1. H:和V:每次都是使用一個
  2. 視圖變量名出如今方括號中,例如[view]
  3. 字符串中順序是按照從頂到底。從左到右
  4. 視圖間隔以數字常量出現,例如-20-
  5. |表示父視圖

使用Auto Layout時須要注意的點

  • 注意禁用 Autoresizing Masks。對於每一個須要使用Auto Layout的視圖須要調用setTranslatesAutoresizingMaskIntoConstraints:NO
  • 佈局原理是由外向里布局,最早屏幕尺寸,在一層一層往裏佈局各個元素的大小
  • 刪除視圖時直接使用removeConstraint和removeConstraints時須要注意這樣刪除是無法刪除視圖不支持的約束致使view中還包含着那個約束(使用第三方庫時須要特別注意下)。解決這個的辦法就是添加約束時用一個局部變量保存下,刪除時進行比較刪掉和先前那個,還有個辦法就是設置標記,constraint.identifier = @「What you want to call」。
  • VFL語句裏不能包含空格和>,<這樣的約束

佈局約束規則

Auto Layout的Debug

  1. Unsatisfiable Layouts 約束衝突,同一時刻約束沒法同時知足
  2. Ambiguous Layouts: 約束缺失
  3. Logical Errors: 佈局中的邏輯錯誤
  4. 視圖約束不合法,每一個約束至少要引用一個視圖,刪除視圖時必定要注意
  5. 無公共父視圖之間的相互添加約束會出問題

推薦使用的Auto Layout 第三方庫

  • Masonry
  • Cartography
  • SDAutoLayout
相關文章
相關標籤/搜索