翻譯@Auto Layout Guide(自動布局指南)
- 原文:Auto Layout Guide
- 作者:Apple
- 更新:Yannmm@Github.com
Getting Started(新手上路)
Working with Constraints in Interface Builder(在界面編輯器中使用約束)
(譯者:界面編輯器克胳,Interface Builder垒迂,以下簡稱IB??)
通過IB創(chuàng)建約束大猛,有三種方式:按住control拖拽艾岂;使用固定和對齊工具(譯者:Pin and Align Tools,其實是IB右下角的兩個按鈕讶隐,后者現(xiàn)在已經(jīng)不叫Align抖拦,改為Add New Constraints);讓IB自動設置诫睬,然后手動修改約束煞茫。以上方式各有所長,大多數(shù)人會選擇一種熟練使用摄凡。但全部了解可以讓我們更好的根據(jù)需要選擇合適的方式续徽。
不論使用哪種方式,都需要先將視圖從對象庫(Object Library)拖拽至畫布亲澡,并調整其大小和位置钦扭。IB會自動創(chuàng)建一組原型約束(prototyping constraints),相對于畫布左上角定義視圖的尺寸和位置床绪。
至此土全,app已經(jīng)可以編譯運行捎琐,展示界面。但隨著開發(fā)的進行裹匙,要逐步添加顯性約束瑞凑。絕對不能發(fā)布使用原型約束的app。
一旦為視圖添加自定義約束概页,所有原型約束會被自動移除籽御。此時,由于缺少約束惰匙,布局歧義技掏。受歧義影響的約束顯示為紅色,Xcode報警告项鬼。
莫慌哑梳,繼續(xù)添加約束,直至布局完整绘盟。添加自定義約束時鸠真,必須做到有始有終。
更多關于修復警告和錯誤的信息龄毡,詳見章節(jié)Debugging Auto Layout(調試自動布局)吠卷。
Control-Dragging Constraints(拖拽生成約束)
要在兩個視圖之間創(chuàng)建約束,可以按住control沦零,將一個視圖拖動至另一個祭隔。
松開鼠標,從彈出的灰色菜單中選擇一個要添加的約束路操。
IB會根據(jù)約束的元素和拖拽的方向疾渴,生成可供選擇的約束。如果沿水平方向拖拽屯仗,則可以設置水平間距搞坝,垂直對齊。如果沿垂直方向拖拽祭钉,則可以設置垂直間距瞄沙,水平對齊己沛。當然慌核,還有許多其他可用約束(例如相對尺寸)匀奏。
注意
可拖拽的對象不僅有畫布上的視圖箫措,也可以是場景對象列表(scene's document outline)中的圖標。特別是畫布上找不到的元素鲜戒,如布局參照(layout guide)师幕。拖拽的對象是后者時粟按,可供選擇的約束不再受拖拽方向影響诬滩。
IB根據(jù)視圖當前frame創(chuàng)建約束。因此灭将,添加約束前疼鸟,要將其移動到合適的位置。一般來說庙曙,根據(jù)系統(tǒng)建議擺放視圖(即視圖在畫布上移動時出現(xiàn)的藍色虛線)空镜,能夠得到符合預期的約束。況且捌朴,隨時可以修改約束吴攒。
拖拽讓我們迅速創(chuàng)建約束;然而砂蔽,由于是根據(jù)當前frame創(chuàng)建洼怔,所以很容易產(chǎn)生偏差。要想更精確左驾,可以在約束創(chuàng)建后逐一檢查并修改镣隶,或使用固定和對齊工具創(chuàng)建約束。
更多關于拖拽創(chuàng)建約束的信息什荣,詳見自動布局幫助(Auto Layout Help)中同拖拽創(chuàng)建約束有關的內容矾缓。
Using the Stack, Align, Pin and Resolve Tools(堆疊,對齊稻爬,固定和問題解決工具的使用)
IB的右下角有四個布局工具:分別是堆疊嗜闻,對齊,固定和問題解決桅锄。
想要更準確的創(chuàng)建約束琉雳,或一次創(chuàng)建多個約束,可以使用固定和對齊工具友瘤。無需提前排布視圖翠肘;只需大致確定視圖的位置,添加約束辫秧,勾選更新frame即可束倍。系統(tǒng)會自動計算視圖位置和尺寸,并在畫布上更新盟戏。
Stack Tool(堆疊工具)
此工具可以快速創(chuàng)建堆疊視圖(UIStackView)绪妹。選中畫布上一個或多個視圖,單擊堆疊工具柿究,這些視圖會被嵌入一個新的堆疊視圖中邮旷,其尺寸由內容決定。
注意
通過這種方式創(chuàng)建的堆疊視圖方向和對齊方式取決于內容視圖的相對位置蝇摸。在屬性面板可以修改各項屬性的值婶肩。
Align Tool(對齊工具)
此工具可以快速對齊視圖办陷。選中要對齊的視圖,點擊對齊工具律歼,有菜單彈出民镜,包含所有可能的對齊方式。
選中一個或多個對齊方式险毁,點擊添加約束(Add Constraints)按鈕殃恒。相應的對齊約束會被添加至視圖。默認辱揭,這些約束沒有任何偏移量(即直接對其)离唐,視圖在畫布上的尺寸和位置也不會自動更新。但是问窃,添加約束之前亥鬓,可以進行設置。
使用對齊工具時域庇,一般選擇兩個或以上視圖嵌戈。然而,俯視圖內水平對齊(Horizontally in Container)或父視圖內垂直對齊(Vertically in Container)可以針對單個視圖添加听皿∈烨海可以同時選中多個對齊方式,一次添加多條約束尉姨,但很少需要這樣做庵朝。
更多信息,詳見自動布局幫助中使用固定和對齊工具添加約束的相關內容又厉。
Pin Tool(固定工具)
此工具能夠快速設置視圖的相對位置和尺寸九府。選中要固定的視圖,點擊固定工具覆致,有菜單彈出侄旬,包含若干選項。
菜單的上半部分用于——相對于四周的鄰近元素——定義視圖四邊煌妈。對應的數(shù)字分別代當前間距儡羔;可以直接修改數(shù)字,也可以點擊隨后的三角形璧诵,選擇系統(tǒng)推薦值汰蜘,或更改參照元素。下方的"保留邊距(Constrain to margins)"表示當參照元素是父視圖時腮猖,相對邊距還是相對四邊約束鉴扫。(譯者:例如赞枕,相對于父視圖的leading約束澈缺,如不勾選坪创,則意味著superView.Leading;反之姐赡,則意味著superView.Leading.Margin莱预。)
菜單的下半部分用于定義視圖寬高。默認是當前frame值项滑,可以修改依沮。寬高比(Aspect Ratio)選項默認是當前frame寬高比,可以在添加約束后修改枪狂。
通常危喉,我們一次只固定一個視圖 。然而州疾,選中兩個或以上視圖辜限,可以約束它們等高或等寬⊙媳停可以一次創(chuàng)建多條約束薄嫡,可以自動更新視圖frame。一旦確定要添加的約束颗胡,點擊添加約束按鈕(Add Constraints)即可毫深。
更多信息,詳見自動布局幫助中使用固定和對齊工具添加約束的相關內容毒姨。
Resolve Auto Layout Issues Tool(問題解決工具)
此工具可以解決許多常見布局問題哑蔫。菜單的上部選項只影響選中視圖,下部選項影響場景中所有元素弧呐。
借助此工具鸳址,我們可以根據(jù)視圖約束更新其frame;也可以根據(jù)視圖frame更新其約束泉懦。還可以添加缺失約束稿黍,清除約束,或者重置視圖崩哩,替換為系統(tǒng)推薦約束巡球。
添加或重置約束的操作在章節(jié):Letting Interface Builder Create Constraints(讓界面編輯器替我們創(chuàng)建約束)中有更詳細的討論。
Letting Interface Builder Create Constraints(界面編輯器自動創(chuàng)建約束)
IB可以自動創(chuàng)建部分邓嘹,甚至所有約束:其基于視圖當前frame推測出合適的約束酣栈。所以請注意視圖的擺放——即使是微小的偏差,也可能導致截然不同的布局結果汹押。
想要利用這一特性矿筝,點擊問題解決工具,選擇重置為推薦約束(Reset to Suggested Constraints)棚贾。IB會自動為選中視圖(或所有視圖)添加約束窖维,產(chǎn)生明確榆综,可滿足的布局。
也可以自行添加一部分約束铸史,然后點擊問題解決工具鼻疮,選擇添加缺失約束(Add Missing Constraints)。系統(tǒng)會補全約束琳轿,類似的判沟,適用于選中視圖或所有視圖。
這一特性讓我們快速創(chuàng)建明確崭篡,可滿足的布局挪哄。然而,除非界面足夠簡單琉闪,否則布局結果可能會和預想不同中燥。所以,要多測試塘偎,確保結果符合預期疗涉。
Finding and Editing Constraints(查找和編輯約束)
添加約束后,還需要能夠定位吟秩,查看咱扣,修改約束。訪問約束的途徑有很多涵防,代表組織和呈現(xiàn)約束的不同方式闹伪。
Viewing Constraints in the Canvas(查看畫布上的約束)
同選中視圖相關的約束會被顯示在畫布上,用藍色線條表示壮池。線條形狀偏瓤,兩端樣式以及顏色能夠透露許多關于約束的信息。
- 工型直線(兩端為T型):代表空間長度椰憋√耍可以是視圖寬高,也可以是兩個視圖的間距橙依。
- 一般直線(兩端無樣式):代表四邊對齊证舟。例如,對齊兩個視圖的前邊窗骑。另外女责,視圖間距為0pt時,也用這種線條表示创译。
- 實線:代表"必要(Required)"約束(優(yōu)先級等于1000)抵知。
- 虛線:代表優(yōu)先級小于1000的約束。
- 紅線:代表受此約束影響的視圖的布局有歧義,或無法滿足刷喜。更多信息残制,可以通過問題導航面板或場景對象列表上方的箭頭查看。
- 橙線:代表受此約束影響的視圖的frame不正確吱肌。橙色虛線代表正確的frame。點擊問題解決工具仰禽,選擇更新frame(Update Frames)即可解決氮墨。
- 藍線:代表受此約束影響的視圖的布局明確,可滿足吐葵,其frame正確规揪。
- 等號標志:代表等高或等寬的約束。受影響的視圖會相應的位置顯示一條藍色T型直線温峭,中間有"="標志猛铅。
- 大于等于或小于等于標志:代表規(guī)定了大于等于或小于等于關系的約束,中間有">="或"<="標志凤藏。
Listing Constraints in the Document Outline(通過場景對象列表查看約束)
所有約束都可以在場景對象列表中找到奸忽,歸類在所屬視圖下方:參與約束的兩個元素的公共父視圖,持有約束揖庄。據(jù)此栗菜,單個視圖持有自身及其子視圖,上下布局參照被根視圖持有蹄梢。
雖然約束散落在列表中疙筹,但大多數(shù)都被根視圖持有。展開完整列表可以查看所有約束禁炒。
列表通過偽代碼表示約束而咆,內容較長,(約束之間)區(qū)分度不高幕袱,特別一個元素下多個約束并排顯示時暴备。可以調整列表寬度们豌,顯示完整信息馍驯。選中列表中的約束,畫布上相應約束會高亮玛痊。
如果布局簡單汰瘫,通過場景對象列表查看約束的確非常方便。但隨著布局復雜度增加擂煞,定位約束會變的非常困難混弥。因此,最好以視圖為單位查看約束:在畫布上選中視圖,查看相關約束蝗拿;或通過尺寸面板查看相關約束晾捏。
Finding Constraints in the Size Inspector(通過尺寸面板中查看約束)
尺寸面板會顯示所有同當前視圖相關的約束。必要約束(優(yōu)先級1000)表示為實線哀托,可選約束表示為虛線惦辛。約束的相關信息在下方顯示,羅列了參與的元素和屬性仓手;還可能包含關系胖齐,常量,系數(shù)及比例的信息嗽冒。
上圖中上方的圖例展示了視圖的哪些屬性受約束影響呀伙。選中某個屬性,下方列表會被過濾添坊,只留下影響當前屬性的約束剿另。
更多信息,詳見自動布局幫助中同查看元素約束有關的內容贬蛙。
Examining and Editing Constraints(檢查和編輯約束)
約束一旦被選中雨女,屬性面板會展示相關信息。例如關系等式的所有組成部分:元素阳准,關系戚篙,常量,系數(shù)溺职;另外還包括優(yōu)先級和識別符等信息岔擂。
注意
identifier
屬性允許我們?yōu)榧s束命名,從而在查看控制臺信息和debug時更好的識別約束浪耘。
另外乱灵,可以將其標記為占位約束(Placeholder)。占位約束只在設計xib時有效七冲。運行時的界面不包含這些約束痛倚,因此無效。舉例來說澜躺,布局中有需要動態(tài)添加的約束蝉稳,我們可以使用占位約束代表動態(tài)約束。這樣掘鄙,可以消除xib的布局警告耘戚,查看運行時的布局效果。
常量操漠,優(yōu)先級收津,系數(shù),關系,識別符撞秋,是否占位长捧,都可以直接修改;但參與約束的元素無法吻贿。元素的位置可以對調(當然系數(shù)和常量需要手動調整)串结。即可以修改元素屬性,但不能更改元素舅列。如果確實需要更改肌割,請刪除約束,重新添加剧蹂。
也可以在視圖的尺寸面板中修改約束声功。點擊任意約束后的Edit(編輯)按鈕烦却,在彈出的菜單中修改關系宠叼,常量,優(yōu)先級和系數(shù)其爵。要做更多修改冒冬,雙擊約束,切換至約束屬性面板摩渺。
更多信息简烤,詳見自動布局幫助中同編輯約束相關的內容。
Setting Content-Hugging and Compression-Resistance Priorities(內縮和外擴優(yōu)先級)
要設置視圖的內縮和外擴優(yōu)先級(CHCR priorities)摇幻,首先選中視圖横侦,然后打開尺寸面板,找到內縮和外擴優(yōu)先級設置绰姻。
還可以設置視圖的占位(Placeholder)固有尺寸枉侧。默認,系統(tǒng)使用intrinsicContentSize的返回值狂芋,作為視圖固有尺寸榨馁。然而,如果固有尺寸能夠在設計xib時確定帜矾,則可以設置一個占位值翼虫。這個尺寸只在設計xib時有效,運行時無效屡萤。
更多信息珍剑,詳見自動布局幫助中同設置視圖占位固有尺寸相關的內容。
iOS-Only Features(iOS獨有特性)
iOS有一些針對自動布局的獨有特性死陆,包括布局參照(layout guide)次慢,視圖留白(layout margin),可讀內容參照(readable content guide),以及語義內容(semantic content)迫像。
Top and Bottom Layout Guides(上下布局參照)
布局參照代表當前控制器可視范圍的上下邊界劈愚。例如,要避免視圖被透明或半透明的欄位阻擋(UIKit bar闻妓,如status bar菌羽,navigtaion bar和tab bar),請相對布局參照約束由缆。
布局參照遵守協(xié)議UILayoutSupport注祖,其定義屬性length
,用于表示布局參照到視圖上下邊緣的距離均唉。特別注意:
- 對于上方布局參照(top layout guide)是晨,其代表控制器視圖上邊與所有上方欄位的最下邊的距離,單位pt舔箭。(例如罩缴,上方有狀態(tài)欄,然后是導航欄层扶,則此時length = 狀態(tài)欄高度 + 導航欄高度)
- 對于下方布局參照(bottom layout guide)箫章,其代表控制器視圖下邊與下方欄位的最上邊的距離,單位pt镜会。(例如檬寂,下方有tab bar,則此時length = tabBar.height)
布局參照可以參與約束戳表,定義視圖的上下及高度桶至。通常,相對于上方布局參照的下邊匾旭,或下方布局參照的上邊約束視圖镣屹。另外,代碼創(chuàng)建約束時季率,還可以使用屬性topAnchor
野瘦,bottomAnchor
及heightAnchor
。
相對根視圖(root view)的上下邊創(chuàng)建約束時飒泻,布局參照會自動作為備選項出現(xiàn)鞭光。如果它們是視圖的最鄰近元素,則默認選中泞遗。使用固定工具(Pin tool)時惰许,通過點擊相應位置的三角形,可以在視圖邊緣和布局參照之間切換史辙。
Layout Margins(布局留白)
自動布局中汹买,視圖有留白(margin)佩伤。所謂留白,就是視圖子視圖與其邊緣之間的推薦距離晦毙。通過訪問視圖屬性layoutMargins或layoutMarginsGuide獲取相關信息生巡。屬性layoutMargins
通過結構體UIEdgeInsets定義留白。只讀屬性layoutMarginsGuide
通過對象UILayoutGuide給出留白见妒。此外孤荣,可以通過視圖屬性preservesSuperviewLayoutMargins規(guī)定視圖留白和父視圖留白之間的關系。
視圖四周留白默認為8pt须揣。當然盐股,可以根據(jù)需要修改。
注意
系統(tǒng)自動設置和管理控制器根視圖的留白耻卡。其上下留白為0pt疯汁,便于將內容置于欄位(UIKit bar)下方(如有)。兩側留白根據(jù)控制器的呈現(xiàn)方式變化卵酪,一般為16或20pt幌蚊。以上數(shù)值無法修改。
相對于父視圖約束時凛澎,一般參照其留白霹肝,而非邊緣估蹄。UIKit中的枚舉NSLayoutAttribute包含一組枚舉值塑煎,分別代表各個方向留白:上下,左右臭蚁,前后最铁;以及基于留白的水平和垂直中心。
在IB中垮兑,通過control拖拽生成的冷尉,相對于父視圖的約束默認參照留白。使用固定工具創(chuàng)建約束時系枪,勾選"Constrain to marings"雀哨,可以在留白和邊緣之間切換。類似的私爷,在屬性面板中編輯約束時雾棺,在元素的下拉菜單中勾選"Relative to margin(相對留白)";其作用和"Constrain to margins"一致衬浑。
最后捌浩,代碼創(chuàng)建約束時,使用父視圖屬性layoutMarginsGuide
工秩。其包含一組錨點尸饺,相對這些錨點創(chuàng)建約束进统,代碼可讀性更好。
Readable Content Guides(可讀內容參照)
視圖屬性readableContentGuide定義視圖中文本對象的最適宜寬度浪听。理想情況下螟碎,用戶無需轉動頭部,即可閱讀全部內容迹栓。
這個區(qū)域相對四邊留白居中抚芦,且絕不會超出四邊留白。其尺寸會根據(jù)系統(tǒng)動態(tài)字體的大小調整迈螟。如果字體變大叉抡,則尺寸變寬;因為用戶在閱讀時答毫,與設備的距離更遠褥民。
可以在IB中設置視圖留白等同于布局留白,還是可讀內容參照洗搂。選中視圖(此時一般是控制器根視圖)消返,打開尺寸面板,勾選"Follow Readable Width"耘拇。如此一來撵颊,任何相對于留白的約束,就是相對于可讀內容參照惫叛。
注意
對于大多數(shù)設備來說倡勇,無論誰扮演視圖留白(布局留白或可讀內容參照),區(qū)別都很小嘉涌,甚至沒有妻熊。只有在橫屏下的iPad,才能看出明顯的區(qū)別仑最。
Semantic Content(語義內容)
使用前后(leading和trailing)布局時扔役,視圖內容方向會自動根據(jù)語言的閱讀方向調整(例如英語的閱讀方向是從左至右,而阿拉伯語從右至左)警医。然而亿胸,某些視圖無須變化,如模擬方位的按鈕(上预皇,下侈玄,左,右)深啤。
視圖屬性semanticContentAttribute規(guī)定內容是否需要根據(jù)語言的閱讀調整拗馒。
點擊視圖屬性面板中的"Semantic",彈出菜單溯街,選項如下:"Unspecified"表示總是反轉诱桂;"Spatial(空間內容)"洋丐,"Playback(播放器)",和"Force Left-to-Right(強制從左至右)"挥等,表示前邊等同于左邊友绝,后邊等同于右邊;"Force Right-to-Left"肝劲,表示前邊等同于右邊迁客,后邊等同于左邊。
Rules of Thumb(規(guī)則總結)
下述規(guī)則能夠幫助我們順利使用自動布局辞槐。當然掷漱,一切都有例外;但在違背規(guī)則之前榄檬,三思而后行卜范。
不手動設置視圖的frame,bounds及center鹿榜。
-
盡量使用堆疊視圖
堆疊視圖能夠自動管理其布局海雪,免除了手動添加約束的麻煩。除非無法滿足需求舱殿,否則不手動布局奥裸。
-
參照最鄰近元素設置約束。
假設有兩個相鄰按鈕A和B沪袭,約束B的前邊時湾宙,參照A的后邊,而非父視圖的前邊(即跨過了A)枝恋。
-
避免固定寬高创倔。
自動布局的優(yōu)勢在于動態(tài)響應變化嗡害,固定寬高意味著將放棄這種優(yōu)勢焚碌。然而,可以限定款高的最大值或最小值霸妹。
設置約束無從下手時十电,可嘗試使用固定和對齊工具。雖然效率不如control拖拽叹螟,但可以明確構成約束的元素和數(shù)值鹃骂,從而有助于我們理清思路。
-
小心使用自動更新frame罢绽。如果視圖布局有歧義或沖突畏线,則結果無法預期。視圖有可能從畫布上消失良价,其原因可以是寬或高為0寝殴,也可以是視圖位于屏幕之外蒿叠。
當然,frame更新后可以撤銷蚣常。
-
為約束添命名市咽,便于區(qū)分。
按鈕或標簽的名稱就是其文本內容抵蚊。對于其他視圖來說施绎,需要在身份面板中設置"label",或者在場景對象列表中雙擊視圖贞绳,填入名稱谷醉。
-
創(chuàng)建約束時,盡量使用前后(leading和trailing)冈闭,而非左右(left和right)孤紧。
通過視圖屬性semanticContentAttribute(iOS)或userInterfaceLayoutDirection(OS X)定義前后。
-
iOS中拒秘,參照控制器根視圖四邊添加約束時号显,最好使用如下約束:
-
水平約束。對于大多數(shù)控件來說躺酒,緊貼留白布局即可(即偏移量為0pt)押蚤。系統(tǒng)會根據(jù)設備類型和控制器的呈現(xiàn)方式自動調整邊距。
對于占據(jù)整個橫向空間的文本視圖來說羹应,相對可讀內容參照布局揽碘。
對于需要完全填充整個空間的視圖來說(例如背景圖片),相對前后布局园匹。
-
垂直約束雳刺。如果視圖需要延伸至欄位(UIKit bar)下方,相對上下留白布局裸违。這是滾動視圖(scroll view)的常見用法掖桦,因為其內容需要在欄位下方滾動。但注意供汛,可能需要調整滾動視圖屬性contentInset和scrollIndicatorInsets枪汪,以確保內容的初始位置正確。
如果視圖不需出現(xiàn)在欄位下方怔昨,則相對上下布局參照約束雀久。
-
代碼布局時,必須將視圖屬性translatesAutoresizingMaskIntoConstraints置為
NO
趁舀。系統(tǒng)默認根據(jù)視圖frame及其自動縮放掩碼生成一組約束赖捌,添加至視圖;這些約束很可能同自定義約束產(chǎn)生沖突矮烹。-
注意OS X和iOS計算布局的方式不同越庇。
在OS X中奋隶,自動布局影響窗口的內容和尺寸。在iOS中悦荒,場景的尺寸和布局不可更改唯欣,自動布局僅影響場景的內容。
上述區(qū)別看似無關緊要搬味,但對于布局設計境氢,特別是約束的優(yōu)先級順序,有著深遠的影響碰纬。