窺探iOS可視化編程中AutoLayout的精髓

在iOS開發中,使用可視化編程能夠簡單快速的拖拽出令人滿意的UI。但是,除了簡單的拖拽之外,還有一項工作對于可視化編程來講必不可少,那就是AutoLayout自適應布局。因為,沒有進行AutoLayout的UI將無法適應屏幕大小不同的機型。本文主要基于Xcode 7.2.1總結一下個人在可視化編程中進行AutoLayout的幾點經驗,大神請繞過。

本文結構圖

一、關于約束

在可視化編程中進行AutoLayout的方法就是添加約束。通過添加合適的約束,使控件能夠按照預期的位置和大小顯示在屏幕大小不同的機型上,也就實現了AutoLayout自適應布局。

1、添加約束

學習過可視化編程的小猿們應該都知道添加約束的幾種主要方法:

方法一:使用 Interface Builder 界面右下角的 Stack 、Align 、Pin 、Resolve Auto Layout Issues 四個約束操作按鈕。

方法二:在 Interface Builder 界面上,按住 control 鍵,從控件開始拖動鼠標到參考控件上,松開鼠標就會彈出約束選擇窗口(如圖 1-1)。

圖 1-1

方法三:在 Interface Builder 界面左側的 Document Outline 窗口中,按住 control 鍵,從控件開始拖動鼠標到參考控件上,松開鼠標就會彈出約束選擇窗口(如圖 1-2)。

圖 1-2


2、約束分類

從上面的截圖中我們可以發現,約束大致上可以分為三類:

2.1 ?距離約束

距離約束主要用于限定控件相對于參考控件的距離關系。相對于不同的參考控件,距離約束的具體名稱會有一些區別,但作用效果基本相同。例如:

相對于根 View 的距離約束為:Leading Space to Container Margin 、Trailing Space to Container Margin 、Vertical Spacing to Top Layout Guide 、Vertical Spacing to Bottom Layout Guide 。

相對于非根 View 的父 View 的距離約束為:Top Space to Container 、Leading Space to Container 、Bottom Space to Container 、Trailing Space to Container 。

相對于無包含關系的其它控件的距離約束為:Horizontal Spacing 、Vertical Spacing 。

2.2 ?對齊約束

對齊約束主要用于限定控件相對于參考控件的距離關系。同樣,相對于不同的參考控件,對齊約束的具體名稱也會有一些區別。例如:

相對于跟 View 或父 View 的對齊約束為:Center Horizontally in Container 、Center Vertically in Container 。

相對于無包含關系的其它控件的對齊約束為:Center Horizontally 、Center Vertically 。

2.3 ?寬高約束

寬高約束主要用于限定控件相對于參考控件的寬高關系,包括:Equal Widths 、Equal Heights 、Aspect Ratio 。

二、窺探精髓

上面講述了關于約束的基本內容,但具有可視化編程經驗的小猿們都清楚,只知道這些基本內容還遠不足以添加出能夠滿足各種 AutoLayout 需求的約束。所以說,接下來我們就深入其中,窺探精髓。

在 Interface Builder 界面中選中某個控件,我們就可以在 右側 Utilities 窗口 —> Size 選項卡 —> Constraints 選項 下查看已經添加的約束(如圖 2-1),并可以點擊 Edit 或者雙擊進入約束詳情對這些約束進行編輯。

圖 2-1

或者我們可以直接在 Interface Builder 界面選中控件上的具體約束,在 右側 Utilities 窗口 —> Size 選項卡 下就會顯示約束詳情(如圖 2-2),可直接進行編輯。

圖 2-2

約束詳情中都包括哪些內容呢?下面我們就來詳細了解一下。

在圖 2-2 中我們可以看到,約束詳情的最上面是約束的名稱,也就是圖中的 Center X Alignment Constraint ;最下面是一個 Placeholder 選項,內容是 Remove at build time ,從字面意思就可以知道,如果選擇了這個選項,編譯時將會移除這個約束,所以說一般情況下我們是不會勾選這個選項的;詳情中剩余的內容也就是需要重點講述的內容,其實這些內容都可以用 NSLayoutConstraint 的屬性進行描述:

First Item:(id firstItem 屬性).(NSLayoutAttribute firstAttribute 屬性),其中的 firstAttribute 屬性是可選的。

Relation:NSLayoutRelation relation 屬性,有三個選項可供選擇:Less Than or Equal(<=)、Equal(=)以及 Greater Than or Equal(>=),默認是 Equal(=)。

Second Item:(id secondItem 屬性).(NSLayoutAttribute secondAttribute 屬性),其中的 secondAttribute 屬性是可選的。

Constant:CGFloat constant 屬性,常數,可以手動輸入,用以對約束進行調整。

Priority:UILayoutPriority priority 屬性,優先級,默認值為1000,可以手動輸入,一般不做修改。

Multiplier:CGFloat multiplier 屬性,系數,可以手動輸入,用以對約束進行調整。

Identifier:NSString *identifier 屬性,約束標識。

這些內容遵循一個公式來限定約束:

First Item =(<=、>=) Multiplier × Second Item + Constant

這個公式就是約束的精髓,也就是可視化編程 AutoLayout 的精髓。公式中 First Item 的 firstAttribute 屬性和 Second Item 的 secondAttribute 屬性是可選的,Multiplier 系數和 Constant 常數可以手動輸入,所以說我們可以通過編輯約束來隨心所欲的修改約束,進而限定控件的位置和大小,實現可視化編程中的各種 AutoLayout 需求。

三、特殊需求

1、Label 的高度自適應

Label 的高度自適應非常簡單。具有可視化編程經驗的小猿們都知道,給 Label 加約束時不添加寬高約束也不會報錯,因為系統默認 Label 的 numberOfLines = 1,height = 20.5,寬度根據文字長短自適應。但有些時候,我們需要使用 Label 顯示一段很長的文本,就需要進行高度自適應:添加約束限定 Label 寬度,在 右側 Utilities 窗口 —> Attributes 選項卡 —> Label 選項 下將 Lines 設置為0。

2、ScrollView 的 AutoLayout

曾經嘗試過在可視化編程中對 ScrollView 進行 AutoLayout 的小猿們都知道,如果我們以 ScrollView 作為參考控件給其上的控件添加寬高約束,系統就會報錯。怎么辦呢?曾經有朋友告訴過我一個使用三方解決的方法,具體是什么三方我不記得了,因為我基本不會用這種方法。

那么我是怎么解決的呢?其實只要清楚問題的根源,我們就可以很簡單的解決它。

我們使用代碼創建 ScrollView 的時候,都必須要給定它的 contentSize 屬性,但是我們在可視化編程時并沒有對這一屬性進行設置。所以,當我們以 ScrollView 作為參考控件給其上的控件添加寬高約束時,系統自然就會報錯。解決問題辦法也就是在給 ScrollView 上的控件添加寬高約束時以除 ScrollView 以外的其它控件作為參考控件。

考慮到我們可能會在 ScrollView 上添加很多個控件,最好的作法就是先在 ScrollView 上添加一個空白 View 作為 contentView ,添加好約束后將需要添加的控件添加到 contentView 上,這時就可以按照正常添加約束的方法給這些控件添加約束了。下面的動畫演示的是在 ScrollView 上添加一個與根 View 等寬、高度為根 View 高度2倍的 contentView ,并添加約束的過程:

圖 3-1

3、TableViewCell 的高度自適應

在實際開發中可能經常會遇到 Cell 的高度要根據顯示的文字的多少進行調整的需求,這種情況下,如果我們通過可視化編程來定制 customCell ,又該怎樣添加約束來使 customCell 的高度能夠自適應呢?

首先,我們要給 customCell 中顯示文字的 Label 添加約束:

第一步:限定 Label 的寬度,但不要限定 Label 的高度,因為 Label 高度自適應之后 customCell 才能高度自適應;

第二步:通過 Leading Space 或 Trailing Space 或 Center.X 限定 Label 在水平方向上的位置;

第三步:限定 Label 的 Top Space 和 Bottom Space 兩個距離約束;

第四步:在 右側 Utilities 窗口 —> Attributes 選項卡 —> Label 選項 下將 Lines 設置為0。

然后,我們要在代碼中設置 TableView 的 estimatedRowHeight 和 rowHeight 屬性:

self.tableView.estimatedRowHeight = 30 ; ? ? // 設置 customCell 的估計高度

self.tableView.rowHeight = UITableViewAutomaticDimension; ? ? // 設置 customCell 自適應高度

這樣,我們就實現了 TableViewCell 的高度自適應。

四、實例演示

接下來根據實際開發中的一個 AutoLayout 需求,來給大家做一個小小的演示。之前一個朋友給提了一個 AutoLayout 的需求,具體的 UI 效果如圖 4-1,要求三個 ImageView 等寬等高,之間的兩個間隔和屏幕邊緣的兩個間隔寬度相等。朋友告訴我說他是在四個間隔區域使用了四個空白的占位 View ,然后再添加如下約束:

1、添加距離約束:限定兩邊的空白 View 與屏幕邊緣的距離為0,限定四個占位 View 與三個 ImageView 兩兩之間的距離為0;

2、添加對齊約束:限定四個占位 View 和三個 ImageView 相對于根 View 豎直居中;

3、添加寬高約束:限定四個占位 View 和三個 ImageView 的高度均為 0.2 × 屏幕高度,限定四個占位 View 的寬度均為 0.07 × 屏幕寬度,限定三個 ImageView 的寬度均為 0.24 × 屏幕寬度。

圖 4-1

如果試著把這些約束添加一遍,就會發現這種方法非常麻煩,還容易出錯。但是,這篇文章讀到這里,我們已經完全沒必要再使用這種浪費空白占位 View 又非常麻煩的方法了。我們完全可以只對三個 ImageView 添加約束來實現圖 4-1中的 UI 效果。計算 Multiplier 系數的過程請自行腦補,下面只演示添加約束的過程:

圖 4-2

Notes:

1、衷于分享,歡迎轉載;

2、博主才疏學淺,敬請批評指正;

3、如果對您有所幫助,我倍感榮幸,也請您點個贊。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,501評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,673評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,610評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,939評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,668評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,004評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,001評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,173評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,705評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,426評論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,656評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,139評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,833評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,247評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,580評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,371評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,621評論 2 380

推薦閱讀更多精彩內容

  • 在iOS開發中,使用可視化編程能夠簡單快速的拖拽出令人滿意的UI。但是,除了簡單的拖拽之外,還有一項工作對于可視化...
    小樣別嘚瑟閱讀 442評論 0 0
  • 發現 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,177評論 4 61
  • power投稿指南3 Use of wordprocessing software It is important...
    鴨梨山大哎閱讀 2,986評論 0 3
  • 一場傾盆的大雨, 把悶熱的天氣淋了又淋。 天空中傳來一絲涼意, 把你燥熱的心撫慰。 你可曾知道, 這樣的因緣要用怎...
    小劇在成長閱讀 108評論 0 3
  • 卵巢癌是死亡率和復發率雙高的婦科惡性腫瘤,60%-75%的患者在初始治療后會復發,初始治療后的2年內是復發的高峰期...
    好益測閱讀 1,474評論 0 0