iOS 佈局進階:你真的會用 autolayout 麼?

前言

iOS 系統已經迎來了 10.3.2 版本,iOS 開發發展至今已經至關成熟了。佈局的方式從 frame、size、center 到現在強大的 autolayout,將 UI 佈局儘可能的「自動化」和「智能化」,在很大程度上減小了程序員的工做量。程序員

可能不少人體會過接手一個老項目通篇的 frame 是有多麼的痛苦。在現現在的開發中,性能沒那麼敏感的時候仍是提倡使用自動佈局(好比 UITableview 的高度自適應用法),以減小大量的 UI 計算。面試

然而不少開發者可能寫出的自動佈局一點也不自動。markdown

autolayout 能夠理解爲:給界面設定規則,讓界面隨着數據的變化而作出符合規則的變化。框架

本篇文章重在解決自動佈局中複雜的相互約束。less

選擇佈局的工具

在「遙遠的」過去,相信你們都用過(或者見別人用過)UIKit 框架的下的 NSLayoutConstraint,用原生的layout 代碼體量之大讓人有些難以接受,好在大牛們寫了一些輪子照福你們,好比業界最有名氣的框架—— Masonry。這裏就不介紹 Masonry 的基礎用法了,相關的文檔已經滿天飛了。工具

關於使用 xib、storyboard 仍是純代碼佈局,你們能夠根據開發項目的進度要求和開發者人數來決定,反正他們佈局的道理是同樣的。oop

爲了直觀性,本文使用 xib 來進行描述。佈局

intrinsicContentSize

首先,咱們得搞清楚 intrinsicContentSize 是什麼。性能

一個 View 的約束肯定須要兩個東西,一個是位置,一個是大小。在平常開發中,咱們發現給 UILabel、UIImageView、UIButton 實例寫約束的時候,只須要給他們位置,而不須要給大小。這是由於它們指定了 intrinsicContentSize(能夠理解爲內部經過內容計算出了一個合理的大小,咱們能夠不用指定它)。學習

指定 intrinsicContentSize 方法:重寫 UIView 中的 -(CGSize)intrinsicContentSize: 方法,在須要改變這個值時調用: invalidateIntrinsicContentSize 方法,告知系統值已改變(咱們能夠自定義指定 intrinsicContentSize 的類)

因此,當咱們不給這三種指定了 intrinsicContentSize 的控件的大小的時候,UI 仍是不會出錯,並且能夠經過 intrinsicContentSize 屬性獲取內部計算事後的大小。

模糊約束

模糊約束,就是 Masonry 中的 lessThanOrEqualTo、greaterThanOrEqualTo,也就是小於等於、大於等於,單獨使用模糊約束很簡單。

example:

需求:上圖中label寬度和高度遵循 intrinsicContentSize,可是長度不能超過父視圖。

實現:Label 距離左邊 10,縱向居中,距離右邊小於等於 10

優先級

優先級就是在兩個約束衝突的時候,優先知足優先級高的約束。

example:

其實一般狀況下的優先級的使用很簡單,這裏我要講的是視圖的優先級,以下圖

這兩個方法相信你們都不陌生(無論有沒有用過),他們派上用場的條件是:該視圖指定了intrinsicContentSize(固有大小),因此 UILabel、UIImageView、UIButton 均可以配置這幾個方法。

做爲一個開發者,有一個學習的氛圍跟一個交流圈子特別重要,這有個iOS交流羣:642363427,無論你是小白仍是大牛歡迎入駐 ,分享BAT,阿里面試題、面試經驗,討論技術,iOS開發者一塊兒交流學習成長!

固然,這是在nib文件裏面進行可視化的配置,在代碼裏面是這樣的(他們是 UIView 的方法):

- (void)setContentHuggingPriority:(UILayoutPriority)priority forAxis:(UILayoutConstraintAxis)axis NS_AVAILABLE_IOS(6_0);
- (void)setContentCompressionResistancePriority:(UILayoutPriority)priority forAxis:(UILayoutConstraintAxis)axis NS_AVAILABLE_IOS(6_0);
複製代碼
  • contentHuggingPriority:拒絕變大優先級

  • ContentCompressionResistancePriority:拒絕縮小優先級

換言之,拒絕變大優先級越高,它就不會變大,拒絕縮小優先級越高,它就不會縮小(額,有點廢話的感受)。舉個例子見道理:

example:

需求:A 和 B 相距 10pt,A 的寬度只能和文本一致(A 儘可能遵照指定的 intrinsicContentSize)

實現:

step 1:先固定A和B的位置,而後他們相距10,把約束加上事後會報警告

step 2:咱們作如下操做就能解決

固然,這只是一個默認狀況(提醒各位,不光是寫業務邏輯,寫佈局也須要考慮極限狀況,這樣才能寫出完美的佈局),當A的文本變化的時候會這樣:

step3:如下的處理就瓜熟蒂落了

固然,到目前爲止算了完成了需求,可是在實際開發中還有一個問題須要考慮,就是A的內容過長,將B擠壓爲0了( _ )

step4:這時候,咱們須要給B一個最小的寬度,避免「人間蒸發」,實現這個並無想象中的那麼簡單,方法也不少,下面只講解一種:

結語

佈局的重點內容無非就以上講解的東西,它們單獨拎出來時,你們都以爲很是的簡單。是否能寫出一個完美無 bug 的佈局,每每須要結合它們使用(固定約束、模糊約束、優先級),當佈局元素不少且極其靈活的時候,纔是考研 iOS 工程師佈局 UI 能力的時候。

你們以爲讀完本篇文章有些許收貨,能夠點贊或留言,以爲寫得太low也能夠點贊留言

相關文章
相關標籤/搜索