[TOC]
以下配方演示了如何處理具有內在內容大小的視圖。 通常,內在內容大小簡化了布局,減少了所需的約束數量。 但是,使用內在內容大小通常需要設置視圖的內容擁抱和抗壓縮(CHCR)優先級,這會增加額外的復雜性。
要查看這些配方的源代碼,請參閱 [Auto Layout Cookbook](https://developer.apple.com/sample-code/xcode/downloads/Auto-Layout-Cookbook.zip) 項目。
## 第一節 簡單的標簽和輸入框
這個配方演示了一個簡單的標簽和輸入框對。 在此示例中,標簽的寬度基于其文本屬性的大小,文本字段將展開和縮小以適合剩余空間。

由于此配方使用視圖的內在內容大小,因此只需要五個約束來唯一地指定布局。 但是,您必須確保您具有正確的CHCR優先級才能獲得正確的調整大小行為。
有關內在內容大小和CHCR優先級的更多信息,請參閱 [Intrinsic Content Size](https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/AutolayoutPG/AnatomyofaConstraint.html#//apple_ref/doc/uid/TP40010853-CH9-SW21)。
### 1.1 視圖和約束
在 Interface Builder中,拖出一個標簽和一個文本字段。 設置標簽的文本和文本字段的占位符,然后設置約束,如圖所示。

1. Name Label.Leading = Superview.LeadingMargin
2. Name Text Field.Trailing = Superview.TrailingMargin
3. Name Text Field.Leading = Name Label.Trailing + Standard
4. Name Text Field.Top = Top Layout Guide.Bottom + 20.0
5. Name label.Baseline = Name Text Field.Baseline
### 1.2 屬性
要使文本字段伸展以填充可用空間,其內容擁抱必須低于標簽的內容。 默認情況下, Interface Builder 應該將標簽的內容設置為251,文本字段設置為250。您可以在“Size inspector”檢查器中對其進行驗證。
| Name | Horizontal hugging | Vertical hugging | Horizontal resistance | Vertical resistance |
| --- | --- | --- | --- | --- |
| Name Label | 251 | 251 | 750 | 750 |
| Name Text Field | 250 | 250 | 750 | 750 |
### 1.3 討論
請注意,此布局僅使用兩個約束(4和5)來定義垂直布局,以及三個約束(1,2和3)來定義水平布局。 根據創建非歧義性,可滿足布局的經驗法則,我們需要每個視圖有兩個水平和兩個垂直約束; 然而,標簽和文本字段的內在內容大小提供了它們的高度和標簽的寬度,消除了對三個約束的需要。
此布局還簡化了文本字段始終高于標簽文本的假設,并使用文本字段的高度來定義與頂部布局指南的距離。 因為標簽和文本字段都用于顯示文本,所以配方使用文本的基線進行對齊。
水平方向,您仍需要定義應展開哪個視圖以填充可用大小。 您可以通過修改視圖的 CHCR 優先級來做到這一點。 在這個例子中,Interface Builder 應該已經將名稱標簽的水平和垂直擁抱優先級設置為 251。因為這大于文本字段的默認值 250,所以文本字段擴展為填充任何額外的空間。
> 注意
> 如果布局可能顯示在控件太小的空間中,則還需要修改壓縮阻力值。 壓縮阻力定義在沒有足夠空間時應截斷哪些視圖。
> 在這個例子中,修改壓縮阻力作為讀者的練習。 如果名稱標簽的文字或字體足夠大; 但是,沒有足夠的空間,產生模糊的布局。 系統然后選擇一個約束斷開,并且文本字段或標簽被截斷。
> 理想情況下,您希望為可用空間創建一個永不過大的布局 - 根據需要使用緊湊尺寸類的替代布局。 但是,在設計支持多種語言和動態類型的視圖時,很難準確預測行可能會變大。 為了以防萬一,修改抗壓性是一個很好的安全閥。
## 第二節 動態高度標簽和文本字段
簡單標簽和文本字段配方通過假定文本字段總是比名稱標簽更高來簡化布局邏輯。 然而,這并不總是正確的。 如果您足夠增加標簽的字體大小,它將擴展到文本字段上方。
此配方根據運行時最高控件動態設置控件的垂直間距。 使用常規系統字體,此配方看起來與簡單標簽和文本字段配方相同(請參見屏幕截圖)。 但是,如果將標簽的字體大小增加到 36.0,則布局的垂直間距將根據標簽的頂部進行計算。

這是一個有點人為的例子。 畢竟,如果增加標簽的字體大小,通常也會增加文本字段的字體大小。 但是,考慮到通過iPhone的可訪問性設置提供額外的額外超大字體,這種技術在混合動態類型和固定大小的控件(如圖像)時證明是有用的。
### 2.1 視圖和約束
像在簡單標簽和文本字段中那樣設置視圖層次結構,但使用更復雜的一組約束:

1. Name Label.Leading = Superview.LeadingMargin
2. Name Text Field.Trailing = Superview.TrailingMargin
3. Name Text Field.Leading = Name Label.Trailing + Standard
4. Name Label.Top >= Top Layout Guide.Bottom + 20.0
5. Name Label.Top = Top Layout Guide.Bottom + 20.0 (Priority 249)
6. Name Text Field.Top >= Top Layout Guide.Bottom + 20.0
7. Name Text Field.Top = Top Layout Guide.Bottom + 20.0 (Priority 249)
8. Name label.Baseline = Name Text Field.Baseline
### 2.2 屬性
要使文本字段伸展以填充可用空間,它的內容擁抱必須低于標簽的內容。 默認情況下,Interface Builder應該將標簽的內容設置為251,文本字段設置為250.您可以在“大小”檢查器中對其進行驗證。
| Name | Horizontal hugging | Vertical hugging | Horizontal resistance | Vertical resistance |
| --- | --- | --- | --- | --- |
| Name Label | 251 | 251 | 750 | 750 |
| Name Text Field | 250 | 250 | 750 | 750 |
### 2.3 討論
這個配方為每個控件使用一對約束。 一個必需的,大于或等于約束條件定義了該控件和布局指南之間的最小距離,而一個可選的約束條件試圖將控件從布局指南中精確地拉到20.0點。
對于較高的約束條件,兩個約束條件都可以滿足,所以系統將它從布局指南中精確定位20.0個點。 但是,對于較短的控制,只有最小距離是可滿足的。 另一個約束被忽略。 這使得自動布局系統可以在運行時隨著控件高度的變化動態地重新計算布局。
> 注意
> 請務必將可選約束的優先級設置為低于默認內容擁抱限制(250)的值。 否則,系統會中斷內容擁抱約束并拉伸視圖,而不是重新定位視圖。
> 在處理使用基線對齊的布局時,這可能會特別令人困惑,因為基線對齊只有在文本視圖顯示在內在內容高度時才有效。 如果系統調整其中一個視圖的大小,則文本可能無法正確排列,盡管具有所需的基線約束。
## 第三節 固定高度的列
此配方將簡單標簽和文本字段配方擴展為標簽和文本字段列。 在這里,所有標簽的后沿對齊。 文本字段的前端和后端對齊,水平位置基于最長的標簽。 然而,與簡單標簽和文本字段配方一樣,此配方通過假定文本字段始終高于標簽來簡化布局邏輯。

### 3.1 視圖和約束
布置標簽和文本字段,然后如圖所示設置約束。

1. First Name Label.Leading = Superview.LeadingMargin
2. Middle Name Label.Leading = Superview.LeadingMargin
3. Last Name Label.Leading = Superview.LeadingMargin
4. First Name Text Field.Leading = First Name Label.Trailing + Standard
5. Middle Name Text Field.Leading = Middle Name Label.Trailing + Standard
6. Last Name Text Field.Leading = Last Name Label.Trailing + Standard
7. First Name Text Field.Trailing = Superview.TrailingMargin
8. Middle Name Text Field.Trailing = Superview.TrailingMargin
9. Last Name Text Field.Trailing = Superview.TrailingMargin
10. First Name Label.Baseline = First Name Text Field.Baseline
11. Middle Name Label.Baseline = Middle Name Text Field.Baseline
12. Last Name Label.Baseline = Last Name Text Field.Baseline
13. First Name Text Field.Width = Middle Name Text Field.Width
14. First Name Text Field.Width = Last Name Text Field.Width
15. First Name Text Field.Top = Top Layout Guide.Bottom + 20.0
16. Middle Name Text Field.Top = First Name Text Field.Bottom + Standard
17. Last Name Text Field.Top = Middle Name Text Field.Bottom + Standard
### 3.2 屬性
在“屬性”檢查器中,設置以下屬性。 特別是,將所有標簽中的文本對齊。 這使您可以使用比文本更長的標簽,并且仍然排列文本字段旁邊的邊緣。
| View | Attribute | Value |
| --- | --- | --- |
| First Name Label | Text | First Name |
| First Name Label | Alignment | Right |
| First Name Text Field | Placeholder | Enter first name |
| Middle Name Label | Text | Middle Name |
| Middle Name Label | Alignment | Right |
| Middle Name Text Field | Placeholder | Enter middle name |
| Last Name Label | Text | Last Name |
| Last Name Label | Alignment | Right |
| Last Name Text Field | Placeholder | Enter last name |
對于每一對,標簽的擁抱內容必須高于文本字段。 同樣,Interface Builder 應該自動執行此操作; 不過,您可以在“大小”檢查器中驗證這些優先級。
| Name | Horizontal hugging | Vertical hugging | Horizontal resistance | Vertical resistance |
| --- | --- | --- | --- | --- |
| First Name Label | 251 | 251 | 750 | 750 |
| First Name Text Field | 250 | 250 | 750 | 750 |
| Middle Name Label | 251 | 251 | 750 | 750 |
| Middle Name Text Field | 250 | 250 | 750 | 750 |
| Last Name Label | 251 | 251 | 750 | 750 |
| Last Name Text Field | 250 | 250 | 750 | 750 |
### 3.3 討論
此配方基本上以簡單標簽和文本字段布局的三個副本開始,一個堆疊在另一個上面。 但是,您需要進行一些添加,以便行正確排列。
首先,通過右對齊每個標簽的文本來簡化問題。 現在您可以使所有標簽具有相同的寬度,并且無論文本的長度如何,都可以輕松對齊它們的尾部邊緣。 此外,由于標簽的抗壓強度大于其內容擁抱度,因此所有標簽都傾向于拉伸而不是擠壓。 將前緣和后緣對齊,并且標簽自然延伸至最長標簽的內在內容尺寸。
因此,您只需要對齊所有標簽的前端和后端。 您還需要對齊所有文本字段的前緣和后緣。 幸運的是,標簽的前沿已經與superview的前沿保證金一致。 類似地,文本字段的后沿都與superview的尾部邊距對齊。 您只需要排列另外兩個邊之一,并且因為所有行都是相同的寬度,所以所有行都將對齊。
有很多方法可以做到這一點。 對于這個配方,給每個文本字段等寬。
## 第四節 動態高度列
這個配方結合了你在動態高度標簽和文本字段配方和固定高度列配方中學到的所有東西。這個配方的目標包括:
* 根據最長標簽的長度對齊標簽的尾部邊緣。
* 文本字段的寬度相同,并且它們的前緣和后緣對齊。
* 文本字段展開以填充超級視圖中的所有剩余空間。
* 行之間的高度基于行中最高的元素。
* 一切都是動態的,所以如果字體大小或標簽文字改變,布局會自動更新。

### 4.1 視圖和約束
像在固定高度列中一樣布置標簽和文本字段; 但是,您需要一些額外的限制。

1. First Name Label.Leading = Superview.LeadingMargin
2. Middle Name Label.Leading = Superview.LeadingMargin
3. Last Name Label.Leading = Superview.LeadingMargin
4. First Name Text Field.Leading = First Name Label.Trailing + Standard
5. Middle Name Text Field.Leading = Middle Name Label.Trailing + Standard
6. Last Name Text Field.Leading = Last Name Label.Trailing + Standard
7. First Name Text Field.Trailing = Superview.TrailingMargin
8. Middle Name Text Field.Trailing = Superview.TrailingMargin
9. Last Name Text Field.Trailing = Superview.TrailingMargin
10. First Name Label.Baseline = First Name Text Field.Baseline
11. Middle Name Label.Baseline = Middle Name Text Field.Baseline
12. Last Name Label.Baseline = Last Name Text Field.Baseline
13. First Name Text Field.Width = Middle Name Text Field.Width
14. First Name Text Field.Width = Last Name Text Field.Width
15. First Name Label.Top >= Top Layout Guide.Bottom + 20.0
16. First Name Label.Top = Top Layout Guide.Bottom + 20.0 (Priority 249)
17. First Name Text Field.Top >= Top Layout Guide.Bottom + 20.0
18. First Name Text Field.Top = Top Layout Guide.Bottom + 20.0 (Priority 249)
19. Middle Name Label.Top >= First Name Label.Bottom + Standard
20. Middle Name Label.Top = First Name Label.Bottom + Standard (Priority 249)
21. Middle Name Text Field.Top >= First Name Text Field.Bottom + Standard
22. Middle Name Text Field.Top = First Name Text Field.Bottom + Standard (Priority 249)
23. Last Name Label.Top >= Middle Name Label.Bottom + Standard
24. Last Name Label.Top = Middle Name Label.Bottom + Standard (Priority 249)
25. Last Name Text Field.Top >= Middle Name Text Field.Bottom + Standard
26. Last Name Text Field.Top = Middle Name Text Field.Bottom + Standard (Priority 249)
### 4.2 屬性
在“屬性”檢查器中,設置以下屬性。 特別是,將所有標簽中的文本對齊。 正確對齊標簽可讓您使用比其文本更長的標簽,并且文本的邊緣仍然排列在文本字段旁邊。
| View | Attribute | Value |
| --- | --- | --- |
| First Name Label | Text | First Name |
| First Name Label | Alignment | Right |
| First Name Text Field | Placeholder | Enter first name |
| Middle Name Label | Text | Middle Name |
| Middle Name Label | Alignment | Right |
| Middle Name Text Field | Placeholder | Enter middle name |
| Last Name Label | Text | Last Name |
| Last Name Label | Alignment | Right |
| Last Name Text Field | Placeholder | Enter last name |
對于每一對,標簽的擁抱內容必須高于文本字段。 同樣,Interface Builder 應該自動執行此操作; 不過,您可以在“大小”檢查器中驗證這些優先級。
| Name | Horizontal hugging | Vertical hugging | Horizontal resistance | Vertical resistance |
| --- | --- | --- | --- | --- |
| First Name Label | 251 | 251 | 750 | 750 |
| First Name Text Field | 250 | 250 | 750 | 750 |
| Middle Name Label | 251 | 251 | 750 | 750 |
| Middle Name Text Field | 250 | 250 | 750 | 750 |
| Last Name Label | 251 | 251 | 750 | 750 |
| Last Name Text Field | 250 | 250 | 750 | 750 |
### 4.3 討論
該配方簡單地結合了動態高度標簽和文本字段以及固定高度列配方中描述的技術。 與動態高度標簽和文本字段配方類似,此配方使用成對約束來動態設置行之間的垂直間距。 與固定高度列配方類似,它使用標簽中的右對齊文本和明確的等寬限制來排列列。
> 注意
> 本示例使用 20.0 點空間來填充視圖和頂部布局指南之間的距離,并在同級視圖之間使用8.0空間。 這具有設定固定的 20 點頂部邊界的效果。 如果您需要一個可自動根據是否存在 bar 進行調整的余量,則必須添加其他約束。 通用技術顯示在 [Adaptive Single View](https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/AutolayoutPG/WorkingwithSimpleConstraints.html#//apple_ref/doc/uid/TP40010853-CH12-SW4) 配方中。 然而,確切的實施對讀者來說是一個挑戰。
正如你所看到的,布局的邏輯開始變得有些復雜; 然而,有幾種方法可以簡化事情。 首先,如前所述,您應盡可能使用堆棧視圖。 或者,您可以對控件進行分組,然后布局組。 這使您可以將單個復雜的布局分解為更小,更易于管理的塊。
## 第五節 兩個等寬按鈕
這個配方展示了兩個相同大小的按鈕。 垂直方向上,按鈕與屏幕底部對齊。 在水平方向上,它們被拉伸以便填充所有可用空間。

### 5.1 視圖和約束
在 Interface Builder 中,將兩個按鈕拖到場景中。 使用場景底部的準則對齊它們。 不要擔心按鈕的寬度相同 - 只需拉伸其中一個按鈕即可填充剩余的水平空間。 大致就位后,設置以下約束條件。 自動布局將計算其正確的最終位置。

1. Short Button.Leading = Superview.LeadingMargin
2. Long Button.Leading = Short Button.Trailing + Standard
3. Long Button.Trailing = Superview.TrailingMargin
4. Bottom Layout Guide.Top = Short Button.Bottom + 20.0
5. Bottom Layout Guide.Top = Long Button.Botton + 20.0
6. Short Button.Width = Long Button.Width
### 5.2 屬性
為按鈕提供可見的背景顏色,以便在設備旋轉時更容易看到其框架如何變化。 另外,為按鈕使用不同的長度標題,以顯示按鈕標題不會影響按鈕的寬度。
| View | Attribute | Value |
| --- | --- | --- |
| Short Button | Background | Light Gray Color |
| Short Button | Title | short |
| Long Button | Background | Light Gray Color |
| Long Button | Title | Much Longer Button Title |
### 5.3 討論
此配方使用按鈕的內在高度,但不計算布局時的寬度。 在水平方向上,這些按鈕的尺寸是明確的,以便它們具有相同的寬度并填充可用空間。 要查看按鈕的內在高度如何影響布局,請將此配方與 Two Equal-Width Views 配方進行比較。 在這個配方中,只有兩個垂直約束,而不是四個。
這些按鈕還給出了具有非常不同長度的標題,以幫助說明按鈕的文字如何影響(或者在這種情況下,不會影響)布局。
> 注意
> 對于這個配方,這些按鈕被賦予了淺灰色的背景色,讓你看到它們的框架。 通常,按鈕和標簽具有透明背景,因此很難(如果不是不可能)看到對其 frame 的任何更改。
## 第六節 三個等寬按鈕
此配方擴展了兩個等寬按鈕配方,以便它使用三個等寬按鈕。

### 6.1 視圖和約束
按照圖示布置按鈕并設置約束。

1. Short Button.Leading = Superview.LeadingMargin
2. Medium Button.Leading = Short Button.Trailing + Standard
3. Long Button.Leading = Medium Button.Trailing + Standard
4. Long Button.Trailing = Superview.TrailingMargin
5. Bottom Layout Guide.Top = Short Button.Bottom + 20.0
6. Bottom Layout Guide.Top = Medium Button.Bottom + 20.0
7. Bottom Layout Guide.Top = Long Button.Bottom + 20.0
8. Short Button.Width = Medium Button.Width
9. Short Button.Width = Long Button.Width
### 6.2 屬性
為按鈕提供可見的背景顏色,以便在設備旋轉時更容易看到其框架如何變化。 另外,為按鈕使用不同的長度標題,以顯示按鈕標題不會影響按鈕的寬度。
| Para | View | Attribute |
| --- | --- | --- |
| Short Button | Background | Light Gray Color |
| Short Button | Title | Short |
| Medium Button | Background | Light Gray Color |
| Medium Button | Title | Medium |
| Long Button | Background | Light Gray Color |
| Long Button | Title | Long Button Title |
### 6.3 討論
添加一個額外的按鈕需要添加三個額外的約束(兩個水平約束和一個垂直約束)。 記住,你沒有使用按鈕的內在寬度,所以你至少需要兩個水平約束來唯一地指定它的位置和大小。 但是,您使用的是按鈕的固有高度,因此您只需要一個額外的約束來指定其垂直位置。
> 注意
> 要快速設置等寬限制,請選擇全部三個按鈕,然后使用 Interface Builder 的Pin工具創建等寬限制。 Interface Builder 自動創建所有這兩個必需的約束。
## 第七節 兩個等距的按鈕
從表面上看,這個配方類似于兩個等寬按鈕配方(請參見屏幕截圖)。 但是,在此配方中,按鈕的寬度基于最長的標題。 如果有足夠的空間,則按鈕僅被拉伸,直到它們都與較長按鈕的固有內容大小相匹配。 任何額外的空間均勻分布在按鈕周圍。

在 iPhone 上,兩個相等寬度按鈕和兩個具有相等間距布局的按鈕在縱向方向上看起來幾乎完全相同。 只有當您將設備旋轉到橫向(或使用更大的設備,如 iPad)時,差異才會變得明顯。
### 7.1 視圖和約束
在 Interface Builder 中,拖出并定位兩個按鈕和三個視圖對象。 將按鈕放在視圖之間,然后如圖所示設置約束。

1. Leading Dummy View.Leading = Superview.LeadingMargin
2. Short Button.Leading = Leading Dummy View.Trailing
3. Center Dummy View.Leading = Short Button.Trailing
4. Long Button.Leading = Center Dummy View.Trailing
5. Trailing Dummy View.Leading = Long Button.Trailing
6. Trailing Dummy View.Trailing = Superview.TrailingMargin
7. Bottom Layout Guide.Top = Leading Dummy View.Bottom + 20.0
8. Bottom Layout Guide.Top = Short Button.Bottom + 20.0
9. Bottom Layout Guide.Top = Center Dummy View.Bottom + 20.0
10. Bottom Layout Guide.Top = Long Button.Bottom + 20.0
11. Bottom Layout Guide.Top = Trailing Dummy View.Bottom + 20.0
12. Short Button.Leading >= Superview.LeadingMargin
13. Long Button.Leading >= Short Button.Trailing + Standard
14. Superview.TrailingMargin >= Long Button.Trailing
15. Leading Dummy View.Width = Center Dummy View.Width
16. Leading Dummy View.Width = Trailing Dummy View.Width
17. Short Button.Width = Long Button.Width
18. Leading Dummy View.Height = 0.0
19. Center Dummy View.Height = 0.0
20. Trailing Dummy View.Height = 0.0
### 7.2 屬性
為按鈕提供可見的背景顏色,以便在設備旋轉時更容易看到其框架如何變化。 此外,為按鈕使用不同長度的標題。 按鈕的大小應根據最長的標題。
| View | Attribute | Value |
| --- | --- | --- |
| Short Button | Background | Light Gray Color |
| Short Button | Title | Short |
| Long Button | Background | Light Gray Color |
| Long Button | Title | Much Longer Button Title|
### 7.3 討論
如您所見,約束集變得復雜。 雖然此示例旨在演示特定技術,但在實際應用程序中,您應該考慮使用堆棧視圖。
在此示例中,您希望在父視圖的 frame 更改時更改空白區域的大小。 這意味著您需要一組相等的寬度約束來控制空白區域的寬度; 但是,您無法在空白區域創建約束。 必須有某種對象,其大小可以約束。
在此配方中,您使用虛擬視圖來表示空白區域。 這些視圖是UIView類的空實例。 在這個配方中,他們被賦予0點高度以最小化他們對視圖層次的影響。
> 注意
> 虛擬視圖會給您的布局增加大量成本,因此您應該明智地使用它們。 如果這些視圖很大,即使它們不包含任何有意義的信息,它們的圖形上下文也會占用大量內存。
> 此外,這些視圖參與視圖層次結構的響應者鏈。 這意味著他們會響應消息,如命中測試,這些消息會沿響應器鏈發送。 如果不小心處理,這些視圖可以攔截并響應這些消息,從而產生難以發現的錯誤。
或者,您可以使用 [UILayoutGuide](https://developer.apple.com/documentation/uikit/uilayoutguide) 類的實例來表示空格。 此輕量級類表示可以參與自動布局約束的矩形框架。 布局指南沒有圖形上下文,它們不是視圖層次結構的一部分。 這使得布局指南非常適合分組項目或定義空白區域。
遺憾的是,您無法在 Interface Builder 中向場景添加布局指南,并且以編程方式創建的對象與基于故事板的場景混合會變得非常復雜。 作為一般經驗法則,使用故事板和界面生成器比使用自定義布局指南更好。
此配方使用大于或等于約束來設置按鈕周圍的最小間距。 必需的約束還保證按鈕總是相同的寬度,并且虛擬視圖也總是相同的寬度(但是,它們可以是與按鈕不同的寬度)。 其余布局主要由按鈕的 CHCR 優先級管理。 如果沒有足夠的空間,虛擬視圖會折疊到 0 點寬度,按鈕會在它們之間劃分可用空間(它們之間的標準間距)。 隨著可用空間的增加,按鈕會擴展,直到達到較大按鈕的固有寬度,然后虛擬視圖開始擴展。 虛擬視圖繼續擴展以填充任何剩余空間。
## 第八節 兩個帶有基于類的布局的按鈕
該配方使用兩組不同的約束。 為 Any-Any 布局安裝一個。 這些約束定義了一對等寬按鈕,與兩個等寬按鈕配方相同。
另一組約束安裝在 Compact-Regular 布局上。 這些約束定義了一對堆疊的按鈕,如下所示。

垂直堆疊的按鈕以縱向方式在 iPhone 上使用。 水平行按鈕用于其他任何地方。
### 8.1 視圖和約束
完全按照兩個等寬按鈕配方的布局布局按鈕。 在 Any-Any size 類中,設置約束1到6。
接下來,將 Interface Builder 的大小類切換到 Compact-Regular 布局。

卸載約束2和約束5,并添加約束7,8和9,如圖所示。

1. Short Button.Leading = Superview.LeadingMargin
2. Long Button.Leading = Short Button.Trailing + Standard
3. Long Button.Trailing = Superview.TrailingMargin
4. Bottom Layout Guide.Top = Short Button.Bottom + 20.0
5. Bottom Layout Guide.Top = Long Button.Botton + 20.0
6. Short Button.Width = Long Button.Width
7. Long Button.Leading = Superview.LeadingMargin
8. Short Button.Trailing = Superview.TrailingMargin
9. Long Button.Top = Short Button.Bottom + Standard
### 8.2 屬性
為按鈕提供可見的背景顏色,以便在設備旋轉時更容易看到其框架如何變化。 此外,為按鈕使用不同長度的標題,以顯示按鈕標題不會影響按鈕的寬度。
| View | Attribute | Value |
| --- | --- | --- |
| Short Button | Background | Light Gray Color |
| Short Button | Title | short |
| Long Button | Background | Light Gray Color |
| Long Button | Title | Much Longer Button Title |
### 8.3 討論
Interface Builder 允許您設置特定于大小的類視圖,視圖屬性和約束。 它允許您為寬度和高度指定三種不同尺寸類(緊湊,任意或常規)的不同選項,總共提供九種不同尺寸類。 其中四個對應于設備上使用的最終尺寸等級(Compact-Compact,Compact-Regular,Regular-Compact和Regular-Regular)。 其余是基本大小類,或兩個或更多大小類的抽象表示(Compact-Any,Regular-Any,Any-Compact,Any-Regular和Any-Any)。
加載給定大小類的布局時,系統會加載該大小類的最具體設置。這意味著 Any-Any 大小類定義了所有視圖使用的默認值。Compact-Any 設置都會影響具有緊湊寬度的所有視圖,而 Compact-Regular 設置僅用于具有緊湊寬度和常規高度的視圖。當視圖的大小類發生變化時(例如,當iPhone從縱向旋轉到橫向時),系統會自動交換布局并為更改設置動畫。
您可以使用此功能為不同的 iPhone 方向創建不同的布局。您也可以使用它來創建不同的 iPad 和 iPhone 布局。特定于大小類的自定義可以根據需要進行擴展或簡化。當然,您擁有的變化越多,故事板變得越復雜,設計和維護就越難。
請記住,您需要確保每個可能的 size 類都有一個有效的布局,包括所有基本 size 類。一般來說,選擇一個布局作為默認布局通常是最簡單的。在任意 size 的類中設計布局。然后根據需要修改最終 size 類。請記住,您可以在更具體的 size 類中添加和刪除項目。
對于更復雜的布局,您可能需要在開始之前繪制 9 x 9 網格的 size 類。使用這些尺寸類的布局填充四個角。然后,網格允許您查看跨多個 size 類共享的約束,并幫助您找到布局和 size 類的最佳組合。
有關使用大小類的詳細信息,請參閱 [Debugging Auto Layout](https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/AutolayoutPG/TypesofErrors.html#//apple_ref/doc/uid/TP40010853-CH22-SW1) 。
>原文地址
>[Views with Intrinsic Content Size ](https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/ViewswithIntrinsicContentSize.html#//apple_ref/doc/uid/TP40010853-CH13-SW1)