[TOC]
在 Interface Builder 中設置自動布局約束有三個主要選項:可以在視圖之間控制拖動,可以使用 Pin 和 Align 工具,并且可以讓 Interface Builder 為您設置約束,然后編輯或修改結果。 每種方法都有其自身的優點和缺點。 大多數開發人員發現他們比其他人更喜歡一種方法; 然而,熟悉所有三種方法可以根據手頭的任務快速切換工具。
對于所有三個選項,首先將視圖和控件從 Object 庫拖到場景中。 調整大小并根據需要放置它們。 當在畫布上放置視圖時,Interface Builder 會自動創建一組原型約束,以定義視圖相對于左上角的當前大小和位置。
該應用程序可以構建和運行原型約束。使用這些約束快速可視化和測試用戶界面,然后用自己的顯式約束替換隱式約束。永遠不要發布帶有原型約束的應用程序。
只要創建第一個約束,系統就會從約束引用的視圖中刪除所有原型約束。 如果沒有原型設計約束,您的布局不再有足夠的約束來唯一確定所有視圖的大小和位置。 它變成了一個模糊的布局。 受影響的約束突然顯示為紅色,并且 Xcode 會生成許多警告。
不要驚慌。 只要繼續添加約束,直到布局完成。 只要添加一個約束,您就有責任添加創建非歧義,可滿足布局所需的所有約束。
有關修復布局警告和錯誤的更多信息,請參閱調 [Debugging Auto Layout](https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/TypesofErrors.html#//apple_ref/doc/uid/TP40010853-CH22-SW1)。
## 控制 - 拖動約束
要在兩個視圖之間創建約束,請按住 Control 鍵單擊其中一個視圖并將其拖動到另一個視圖。

釋放鼠標時,Interface Builder 將顯示一個 HUD 菜單,其中包含可能的約束列表。

Interface Builder 根據正在約束的項目和拖動手勢的方向,智能地選擇一組約束。 如果水平拖動或多或少,可以選擇設置視圖之間的水平間距,以及垂直對齊視圖的選項。 如果垂直拖動或多或少,可以選擇設置垂直間距,以及水平對齊視圖的選項。 這兩種手勢都可能包含其他選項(例如設置視圖的相對大小)。
> 注意
> 可以在畫布上的項目以及場景文檔大綱中的圖標上使用控制拖動手勢。 當試圖為難以找到的項目繪制約束時,這通常很有用,例如頂部或底部布局指南。 拖放到文檔大綱或從文檔大綱拖出時,Interface Builder 不會根據手勢的方向過濾可能的約束列表。
Interface Builder 根據視圖的當前幀創建約束。 因此,在繪制約束之前,需要仔細定位視圖。 如果根據 Interface Builder 的指導原則排列視圖,則最終應該有一組合理的約束條件。 如有必要,隨后可以隨時編輯約束。
控件拖動提供了一種設置約束的非常快速的方法; 然而,因為約束的值是從場景當前的布局中推斷出來的,所以很容易以一個點結束。 如果希望更好地進行控制,請在創建約束后查看和編輯約束,或者使用“Pin”和“Align”工具。
有關控制拖動約束的更多信息,請參閱 Adding Layout Constraints by Control-Dragging in Auto Layout Help 。
## 使用 Stack, Align, Pin 和 Resolve工具
界面生成器在編輯器窗口的右下角提供四個自動布局工具。 這些是 Stack,Align,Pin 和 Resolve Auto Layout Issues 工具。

在制定約束條件或想要一次制定多個約束條件時,如果要精細控制,請使用“Pin”和“Align”工具。 作為一個附加優勢,當使用這些工具時,在創建約束之前不需要精確放置視圖。 相反,可以大致設置視圖的相對位置,添加約束,然后更新框架。 這可讓 Auto Layout 為您計算正確的位置。
### Stack 工具
堆棧工具允許快速創建堆棧視圖。 在布局中選擇一個或多個項目,然后單擊堆棧工具。 Interface Builder 將所選項目嵌入到堆棧視圖中,并根據其內容將堆棧調整為當前配件大小。
> 注意:系統從視圖的初始相對位置推斷堆棧的軸和對齊。 您可以使用屬性檢查器修改軸和對齊方式(并設置分布和間距)。
### Align 工具
對齊工具可讓您快速對齊布局中的項目。 選擇要對齊的項目,然后單擊對齊工具。 Interface Builder 提供了一個包含許多可能對齊的彈出視圖。

選擇對齊所選視圖的選項,然后單擊添加約束按鈕。 Interface Builder創建確保這些對齊所需的約束。 默認情況下,約束沒有任何偏移量(邊或中心相互對齊),并且在添加約束時沒有更新幀。 您可以在創建約束之前更改任何這些設置。
在使用對齊工具之前,通常選擇兩個或更多視圖。 但是,容器中的水平或容器中的垂直可以添加到單個視圖中。 可以使用彈出窗口來創建任意數量的約束,但每次創建多于一或兩個是沒有意義的。
有關更多信息,請參閱 Adding Auto Layout Constraints with the Pin and Align Tools in Auto Layout Help 。
### Pin 工具
Pin 工具可讓您快速定義相對于其鄰居的視圖位置,或快速定義其大小。 選擇要固定其位置或大小的項目,然后單擊“Pin”工具。 Interface Builder 提供了一個包含多個選項的彈窗視圖。

彈出窗口的頂部可讓您將選定項目的 Leading,Top,Trailing 或 Bottom 邊緣固定到最近的鄰居。 關聯的數字表示畫布中各項目之間的當前間距。 可以輸入自定義間距,也可以單擊顯示三角形來設置它應該約束的視圖或選擇標準間距。 “Constrain to margins”復選框確定對父視圖的約束是使用父視圖的邊距還是其邊緣。

彈出窗口的下半部分可讓您設置項目的寬度或高度。 寬度和高度約束默認為當前畫布大小,但可以鍵入不同的值。 長寬比約束還使用該項目的當前寬高比; 但是,如果要更改此比例,則需要在創建后檢查并編輯約束。
通常情況下,你選擇一個單一的視圖來釘住; 但是,可以選擇兩個或更多個視圖,并給它們相同的寬度或相等的高度。 也可以一次創建多個約束,或者您可以在添加約束時更新這些框架。 設置完所需選項后,單擊添加約束按鈕以創建約束。
有關更多信息,請參閱 Adding Auto Layout Constraints with the Pin and Align Tools in Auto Layout Help 。
### Resolve Auto Layout Issues 工具
解決自動布局問題工具提供了許多用于修復常見自動布局問題的選項。 菜單上半部分的選項僅影響當前選定的視圖。 下半部分的選項影響場景中的所有視圖。

您可以使用此工具根據當前約束更新視圖的框架,也可以根據視圖在畫布中的當前位置更新約束。 您還可以添加缺少的約束,清除約束或將視圖重置為由Interface Builder推薦的一組約束。
有關添加或重置約束的命令將在 Letting Interface Builder 創建約束中進行更詳細的討論。
## 讓 Interface Builder 創建約束
Interface Builder 可以為你創建一些或所有的約束條件。使用這種方法時,Interface Builder 嘗試根據畫布中視圖的當前大小和位置來推斷最佳約束。請務必仔細定位視圖 - 小間距的差異可能會導致顯著不同的布局。
要讓 Interface Builder 創建所有約束,請單擊` Resolve Auto Layout Issues tool > Reset to Suggested Constraints` 。 Interface Builder 為所選視圖(或場景中的所有視圖)創建所有必需的約束。
或者,您可以自己添加一些約束,然后單擊 `Resolve Auto Layout Issues tool > Add Missing Constraints` 。該選項添加了具有非歧義布局所需的約束。再次,可以將約束添加到所選視圖或場景中的所有視圖。
這種方法可以讓您快速構建一個不模糊的可滿足的布局,但除非用戶界面簡單明了,否則最終的布局可能無法按照您的方式運行。始終測試用戶界面并修改約束,直到獲得預期結果。
## 查找和編輯約束
添加約束后,您需要能夠找到它,查看它并對其進行編輯。 有許多選項可用于訪問約束。 每個選項都提供了一種組織和呈現約束的獨特方法。
### 查看畫布中的約束
編輯器將所有影響當前所選視圖的約束顯示為畫布上的彩色線條。 形狀,筆畫類型和線條顏色可以告訴您很多關于約束的當前狀態。
* I 型線條(帶T形端蓋的線條)。I型線條顯示空間的大小。 這個空間可以是兩個物品之間的距離,或者物品的高度或寬度。
* 普通線條(沒有端蓋的直線)。 簡單線條顯示邊緣對齊的位置。 例如,Interface Builder 在對齊兩個或多個視圖的前沿時使用簡單的線條。 這些線條也可用于連接它們之間具有0點空間的物品。
* 實線。 實線代表所需的約束條件(優先級= 1000)。
* 虛線。 虛線表示可選約束(優先級<1000)。
* 紅線。 受此約束影響的項目之一有錯誤。 該項目有不明確的布局,或其布局不令人滿意。 有關更多信息,請參閱 issues navigator 或 Interface Builder 概要視圖中的公開箭頭。
* 橙色線。 橙色線條表示基于當前約束條件,受此約束影響的其中一個項目的框架不在正確的位置。 界面生成器還以虛線輪廓顯示框架的計算位置。 您可以使用`Resolve Auto Layout Issues tool > Update Frames`命令將項目移動到其計算的位置。
* 藍線。 受約束影響的項目具有非歧義的可滿足的布局,并且項目的框架處于由自動布局引擎計算的正確位置。
* 等于徽章。 Interface Builder 顯示約束條件,使兩個項目的寬度相等或高度與每個項目單獨的欄相同。 兩個 bar 都標有一個藍色徽章,里面包含一個相同的(=)符號。
* 大于等于和小于等于徽章。 Interface Builder 使用里面的一個大于等于或小于等于關系的小藍色徽章來標記所有約束。

### 列出 Document Outline 中的約束條件
Interface Builder 列出 Document Outline 中的所有約束,將它們分組在保存它們的視圖下。 約束由包含約束中的兩個項目的最近視圖保存。 對于此計算,每個視圖包含自身及其所有子視圖,而頂部和底部布局指南包含在場景的根視圖中。

盡管約束可能圍繞大綱傳遞,但大多數約束最終會在場景的根視角下出現。 如果你想確保你找到了所有的約束條件,請展開整個視圖層次結構。
約束條件使用偽代碼列出。 這些列表通常很長,并且通常以相似的視圖集合開始,所以可能必須增加大綱視圖的寬度才能看到有意義的信息。 在大綱中選擇約束會突出顯示畫布中的約束。 使用此功能可幫助您快速確定要檢查的約束。
對于簡單的場景,大綱是瀏覽所有場景約束的好地方。 但是,隨著布局變得越來越復雜,很快就很難找到具體的限制條件。 通常情況下,通過選擇畫布中的視圖或通過檢查“Size inspector”中的視圖,最好一次檢查一個視圖中的約束。
### 在 Size Inspector 中查找約束
Size Inspector 列出影響當前所選視圖的所有約束。 所需約束以實心輪廓顯示,可選約束以虛線輪廓顯示。 說明列出了有關約束的重要信息。 它始終包含受影響的屬性和約束中的其他項目。 它也可能包括關系,常數值和乘數或比率。

上面截圖頂部的圖表顯示了哪些屬性受到約束的影響。 您可以通過選擇一個或多個圖的屬性來過濾約束列表。 該列表然后僅顯示影響所選屬性的那些約束。
有關更多信息,請參閱 Viewing the Complete List of Layout Constraints for an Item in Auto Layout Help 。
### 檢查和編輯約束
當在畫布或 Document Outline 中選擇約束時,屬性檢查器將顯示所有約束的屬性。 這包括約束方程中的所有值:第一項,關系,第二項,常數和乘數。 屬性檢查器還顯示約束的優先級及其標識符。

> 注意
> 約束的標識符屬性允許您提供描述性名稱,以便您可以更輕松地識別控制臺日志和其他調試任務中的約束。
也可以將約束標記為占位符。 這些約束僅在設計時存在。 當應用程序運行時,它們不包含在布局中。 當計劃在運行時動態添加約束時,通常會添加占位符約束。 通過臨時添加創建非歧義,可滿足布局所需的約束,可以清除 Interface Builder 中的任何警告或錯誤。
可以自由修改常量,優先級,乘數,關系,標識符和占位符屬性。 然而,對于第一項和第二項,您的選擇更加有限。 可以交換第一項和第二項(根據需要反轉乘數和常數)。 也可以更改項目的屬性,但不能更改項目本身。 如果需要將約束移至完全不同的項目,請刪除約束并將其替換為新的約束。
Size inspector 也可以直接進行一些編輯。 單擊任何約束中的編輯按鈕會彈出一個彈出窗口,您可以在其中更改約束關系,常量,優先級或乘數。 要進行其他更改,請雙擊該約束以將其選中并在“Attribute”檢查器中將其打開。

有關更多信息,請參閱 Editing Auto Layout Constraints in Auto Layout Help 。
## 設置 Content-Hugging 和 Compression-Resistance 優先級
要設置視圖的內容擁抱和壓縮阻力優先級(CHCR優先級),請在畫布或文檔大綱中選擇視圖。 打開尺寸檢查器,然后向下滾動,直到找到內容擁抱優先級和壓縮阻力優先級設置。

還可以在 Interface Builder 中設置視圖的固有大小。 默認情況下,Interface Builder 使用從視圖的 `intrinsicContentSize` 方法返回的大小。 但是,如果在設計時需要不同的大小,則可以設置占位符固有內容大小。 此占位符僅在 Interface Builder 中影響視圖的大小。 它在運行時對視圖沒有任何影響。
有關更多信息,請參閱 Setting the Placeholder Intrinsic Size for a Custom View in Auto Layout Help 。
## iOS 特性
iOS 添加了一些與自動布局交互的獨特功能。 其中包括頂部和底部布局指南,視圖的布局邊距,視圖的可讀內容指南以及視圖的語義內容。
### 頂部和底部布局指南 Top and Bottom Layout Guides
頂部和底部布局指南代表當前活動視圖控制器的可見內容區域的上邊緣和下邊緣。 如果不希望自己的內容在透明或半透明的 UIKit 欄(例如狀態欄,導航欄或選項卡欄)下展開,請使用自動布局將內容固定到相應的布局設計指南。
布局指南采用 [UILayoutSupport](https://developer.apple.com/documentation/uikit/uilayoutsupport) 協議,為指南提供了一個長度屬性,用于衡量指南與視圖各邊之間的距離。 特別:
* 對于頂部布局指南,長度指示視圖控制器視圖的頂部與覆蓋視圖的最底部條(如導航條)的底部之間的距離(以點為單位)。
* 對于底部布局指南,長度指示視圖控制器視圖底部與覆蓋視圖的欄頂部(例如選項卡欄)之間的距離(以點為單位)。
這些指南還可以充當約束中的項目,支持頂部,底部和高度屬性。 通常,您將視圖限制為頂部布局指南的底部屬性或底部布局指南的頂部屬性。 指南還提供了 topAnchor,bottomAnchor 和 heightAnchor 屬性,以簡化約束的程序化創建。
在根視圖的頂部或底部邊緣創建約束時,Interface Builder 自動提供頂部和底部布局指南作為選項。 如果布局指南是視圖的最近鄰居,則 Interface Builder 默認使用該指南。 當使用 Pin 工具時,可以根據需要在布局指南和根視圖的邊緣之間切換。 只需點擊顯示三角。
### 布局邊距 Layout Margins
自動布局為每個視圖定義邊距。 這些邊距描述了視圖邊緣與其子視圖之間的首選間距。 可以使用 [layoutMargins](https://developer.apple.com/documentation/uikit/uiview/1622651-layoutmarginsguide) 或 [layoutMarginsGuide](https://developer.apple.com/documentation/uikit/uiview/1622566-layoutmargins) 屬性訪問視圖的邊距。 layoutMargins 屬性允許您將邊距設置為 UIEdgeInsets 結構。 layoutMarginsGuide 屬性為 UILayoutGuide 對象提供對邊距的只讀訪問權限。 此外,使用 [preservesSuperviewLayoutMargins](https://developer.apple.com/documentation/uikit/uiview/1622653-preservessuperviewlayoutmargins) 屬性來確定視圖的邊距如何與其父視圖邊距交互。
默認邊距是每邊8個點。 可以根據您的應用需求修改這些邊距。
> 注意
> 系統設置和管理視圖控制器根視圖的邊距。 頂部和底部邊距設置為零點,方便很容易地擴展工具條內的內容(如果有的話)。 側邊距取決于控制器的顯示方式和位置,可以是16點或20點。 無法更改這些邊距。
約束視圖到其父視圖時,通常使用布局邊距而不是視圖的邊緣。 在 UIKit 中, [NSLayoutAttribute](https://developer.apple.com/documentation/uikit/nslayoutattribute) 枚舉定義了一些屬性來表示頂部,底部,前導,尾部,左側和右側邊距。 它還包括 centerX 和 centerY 相對于邊距的屬性。
在界面構建器中,控件拖動視圖和其父視圖之間的約束,默認情況下使用邊距屬性。 當使用 Pin 工具時,可以切換“Constrain to margins”復選框。 如果選中,則所得到的約束使用父視圖的邊距屬性。 如果未選中,則使用父視圖的邊緣。 同樣,在屬性檢查器中編輯約束時,第一項和第二項的下拉菜單中包含“相對于邊距”選項。 選擇此項目以使用邊距屬性。 取消選擇它以使用邊緣。
最后,當以編程方式為超視圖邊距創建約束時,請使用 layoutMarginsGuide 屬性并直接使用布局指南創建約束。 這使可以使用指南的布局定位點來創建約束條件,從而提供易于閱讀的簡化 API 。
### 可讀的內容指南 Readable Content Guides
視圖的 [readableContentGuide](https://developer.apple.com/documentation/uikit/uiview/1622644-readablecontentguide) 屬性包含一個布局指南,該指南定義視圖內文本對象的最大最佳寬度。 理想情況下,內容足夠窄,用戶無需移動頭部即可閱讀。
本指南始終集中在視圖的布局邊界內,并且永遠不會超出這些邊界。 指南的大小也取決于系統動態類型的大小。 當用戶選擇較大的字體時,系統會創建更寬的指南,因為用戶通常在閱讀時將設備遠離它們。
在 Interface Builder 中,可以設置視圖的邊距是否代替布局邊距指南和可讀內容指南。 選擇視圖(通常是視圖控制器的根視圖),然后打開“Size inspector"。 如果勾選 **Follow Readable Width** 復選框,則繪制到視圖邊緣的任何約束都將使用可讀的內容指南。
> 注意
> 對于大多數設備來說,可讀內容指南和布局邊距之間幾乎沒有區別。 只有在進行 iPad 橫向操作時,區別才會變得明顯。
### 語義內容 Semantic Content
如果使用前后約束布置視圖,則在從左到右語言(如英語)和從右向左語言(如阿拉伯語)之間切換時,視圖會自動翻轉位置。 但是,一些界面元素不應該根據閱讀方向改變其位置。 例如,基于物理方向(上,下,左,右)的按鈕應始終保持相同的相對方向。
視圖的 [semanticContentAttribute](https://developer.apple.com/documentation/uikit/uiview/1622461-semanticcontentattribute) 屬性確定在從左到右和從右到左語言之間切換時視圖的內容是否應該翻轉。
在界面生成器中,在屬性檢查器中設置語義選項。 如果值為未指定,則視圖的內容隨著閱讀方向翻轉。 如果將其設置為 `Spatial, Playback, or Force Left-to-Right`,則內容始終按照左邊的前邊緣和右邊的后邊緣布置。`Force Right-to-Left` 總是將前導邊緣置于右側,后緣置于左側。
## 經驗法則
下面的指導方針將幫助您成功地實現自動布局。毫無疑問,每個規則都有一些合法的例外。然而,如果你決定轉向自動布局,在繼續之前停下來仔細考慮一下你的方式。
* 不要使用框架、邊界或中心屬性指定視圖的幾何形狀。
* 切勿使用其框架,邊界或中心屬性來指定視圖的幾何。盡可能使用堆棧視圖,堆棧視圖管理其內容的布局,極大地簡化了其余布局所需的約束邏輯。 只有在堆棧視圖不提供您需要的行為時才會使用自定義約束。
* 在視圖和其最近的鄰居之間創建約束。如果有兩個相鄰的按鈕,則將第二個按鈕的前沿限制在第一個按鈕的后沿。 第二個按鈕通常不應該具有通過第一個按鈕到達視圖邊緣的約束。
* 避免給視圖固定的高度或寬度。自動布局的要點是動態響應變化。 設置固定大小會消除視圖的適應能力。 但是,您可能需要為視圖設置最小或最大尺寸。
* 如果您在設置約束時遇到問題,請嘗試使用“Pin”和“Align”工具。 雖然這些工具可能比 Control 拖動稍慢,但它們確實可以讓您在創建約束之前驗證確切的值和項目。 這額外的健全檢查可以是有益的,特別是當你第一次出發。
* 自動更新項目的框架時要小心。 如果該項目沒有足夠的約束來完全指定其大小和位置,則更新的行為是未定義的。 視圖通常會消失,因為它們的高度或寬度被設置為零,或者因為它們意外地位于屏幕外。可以隨時嘗試更新項目的框架,并在必要時撤消更改。
* 確保布局中的所有視圖都有有意義的名稱。 這使得使用這些工具時識別您的視圖變得更加容易。系統根據文字或標題自動命名標簽和按鈕。 對于其他視圖,可能需要在“標識”檢查器中設置特定于 Xcode 的標簽(或通過雙擊并編輯文檔大綱中的視圖名稱)。
* 始終使用頭和尾約束,而不是右和左。始終可以使用其 [semanticContentAttribute](https://developer.apple.com/documentation/uikit/uiview/1622461-semanticcontentattribute) 屬性(iOS)或其 [userInterfaceLayoutDirection](https://developer.apple.com/documentation/appkit/nsview/1483254-userinterfacelayoutdirection) 屬性(OS X)來調整視圖如何解釋其前緣和后緣。
* 在iOS中,將項目限制在視圖控制器根視圖的邊緣時,請使用以下約束條件:
* Horizontal constraints:對于大多數控件,對布局邊距使用零點約束。 系統根據設備的位置以及應用程序如何顯示視圖控制器自動提供正確的間距。對于從邊距到邊距填充根視圖的文本對象,請使用可讀的內容指南而不是布局邊距。對于需要從邊到邊填充根視圖的項目(例如,背景圖像),請使用視圖的前緣和后緣。
* Vertical constraints:如果視圖在 bar 下方延伸,請使用頂部和底部邊距。 對于滾動視圖來說這尤其常見,允許內容在 bar 下滾動。 但請注意,可能需要修改滾動視圖的 [contentInset](https://developer.apple.com/documentation/uikit/uiscrollview/1619406-contentinset) 和 [scrollIndicatorInsets](https://developer.apple.com/documentation/uikit/uiscrollview/1619427-scrollindicatorinsets) 屬性以正確設置內容的初始位置。如果視圖沒有在小節下面延伸,請將視圖限制為頂部和底部布局指南。
* 以編程方式實例化視圖時,請務必將其 [translatesAutoresizingMaskIntoConstraints](https://developer.apple.com/documentation/uikit/uiview/1622572-translatesautoresizingmaskintoco) 屬性設置為 NO 。 默認情況下,系統根據視圖的frame 和 autoresizing mask 自動創建一組約束。 當添加自己的約束時,它們不可避免地與自動生成的約束發生沖突。 這創建了一個令人無法容忍的布局。
* 請注意,OS X 和 iOS 以不同的方式計算其布局。
* 在OS X中,自動布局可以修改窗口內容和窗口大小。
* 在iOS中,系統提供場景的大小和布局。 自動布局只能修改場景的內容。
這些差異看起來相對較小,但它們可能會對設計布局的方式產生深遠影響,尤其是對于如何使用優先級。
>原文地址
>[Working with Constraints in Interface Builder ](https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/WorkingwithConstraintsinInterfaceBuidler.html#//apple_ref/doc/uid/TP40010853-CH10-SW1)