你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> iOS 9 新增 UIStackView 官方文檔翻譯

iOS 9 新增 UIStackView 官方文檔翻譯

編輯:IOS開發基礎

1.jpg

一、繼承關系、遵守協議、隸屬框架及可用平台

blob.png

UIStackView 類提供了一個高效的接口用於平鋪一行或一列的視圖組合。Stack視圖使你依靠自動布局的能力,創建用戶接口使得可以動態的調整設備朝向、屏幕尺寸及任何可用范圍內的變化。Stack視圖管理著所有在它的 arrangedSubviews 屬性中的視圖的布局。這些視圖根據它們在 arrangedSubviews 數組中的順序沿著 Stack 視圖的軸向排列。精確的布局變量根據 Stack 視圖的 axis, distribution, alignment, spacing, 和其它屬性共同決定。

blob.png

使用 stack 視圖,打開一個你希望編輯的 Storyboard,從對象庫中拖拽出一個 Horizontal Stack View 或者一個 Vertical Stack View,並放置到你希望的位置上。下一步,將控件或視圖拖拽放置到 stack 中,如果需要你可以繼續添加視圖或者控件給指定的 stack。Interface Builder 將根據 stack 的內容自動調節尺寸。你也可以通過修改屬性面板中 Stack視圖的屬性調整 stack 內容的外觀。

注意:你需要負責指定 stack 視圖的位置和尺寸(可選的)。然後 stack 視圖將管理其內容的布局和尺寸。

二、Stack 視圖與自動布局

Stack 視圖使用自動布局來定位和控制其管理的視圖的尺寸。stack 視圖沿著它的軸向拼湊第一個和最後一個被管理視圖,使其邊界平齊。對於一個水平 stack 視圖,這意味著第一個被管理視圖的左邊界是與 stack 的左邊界平齊的,並且最後一個被管理視圖右邊界與 stack的右邊界平齊。對於垂直 stack,上邊界和下邊界是各自平齊的。如果你設置了 stack 視圖的 layoutMarginsRelativeArrangement 屬性為 YES,stack 視圖將使用相關的邊距與其內容對齊,而不是邊界。

對於除去 UIStackViewDistributionFillEqually 分布以外的分布方式,stack 視圖使用被管理視圖的 intrinsicContentSize 屬性來計算沿著 stack 軸向的視圖尺寸。UIStackViewDistributionFillEqually 分布將調節所有被管理視圖的在 stack 軸向上擁有相同尺寸,以填充 stack 視圖。如果可能,stack 視圖將拉伸所有被管理視圖,來匹配其在 stack 軸向上最長的原有尺寸(譯注:保證長寬比的情況下根據 stack 軸向長度拉伸視圖)。

對於除去 UIStackViewAlignmentFill 對齊方式以外的對齊方式,stack 視圖使用其管理的視圖的 intrinsicContentSize 屬性來計算視圖垂直於 stack 軸向的尺寸。 UIStackViewAlignmentFill 重新調節了所有其管理的視圖,使這些視圖填充 stack 視圖垂直於其軸向空間。如果可能,stack 視圖將拉伸其所有管理的視圖來匹配其垂直於 stack 軸向的最大固有尺寸。

blob.png

三、定位和調整 Stack 視圖尺寸

當 Stack 視圖允許你布局其內容而不直接使用自動布局,你將仍然需要使用自動布局來定位 stack 視圖。通常情況下,這意味著需要拼湊至少兩個邊界相鄰的stack來定義它的位置。沒有額外約束的情況下,系統會為 stack 視圖計算一個尺寸來適應其內容:

  • 沿著 stack 視圖軸向,其適應尺寸等於其管理的視圖尺寸與間距的和;

  • 垂直於 stack 視圖軸向,其適應尺寸等於其管理的視圖中最大的視圖的尺寸;

  • 如果 stack 視圖的 layoutMarginsRelativeArrangement 屬性設置為 YES,stack 視圖的適應尺寸會包括邊距空間。

你可以提供額外的約束來具體說明 stack 視圖的高度、寬度或者兩者兼有。在這些情況下,stack 視圖調整了其管理的視圖的布局和尺寸來填充指定區域。精確的布局變量根據 stack 視圖的屬性獲得。可以通過查看 UIStackViewDistribution 和 UIStackViewAlignment 枚舉,以獲得一個完整的 stack 視圖在其內容空間多余或空間不足情況下的處理描述。

你也可以根據 stack 視圖的第一條或最後一條基線定位它,而不是使用頂部、底部或者中心的Y值。類似於 stack 視圖的適應尺寸,這些基線都是基於 stack 視圖的內容計算得到的。

  • 一個水平的 stack 視圖調用 viewForFirstBaselineLayout 方法或 viewForLastBaselineLayout 方法時返回它最高的視圖。如果最高的視圖也是一個 stack 視圖,那麼其返回的將是在嵌套的 stack 視圖上調用 viewForFirstBaselineLayout 方法或 viewForLastBaselineLayout 方法的結果。

  • 一個垂直的 stack 視圖當調用 viewForFirstBaselineLayout 方法時返回的是其管理的第一個視圖,當調用 viewForLastBaselineLayout 方法時返回的是其管理的最後一個視圖。如果這兩個視圖之一也是 stack 視圖,那麼其返回的將是在嵌套的 stack 視圖上對應調用 viewForFirstBaselineLayout 方法或 viewForLastBaselineLayout 方法的結果。

注意:基線對齊方式只作用於那些高度匹配其原本內容高度的視圖。如果視圖被拉伸或壓縮過,那麼基線將出現在錯誤的位置上。

四、通用 Stack 視圖布局

這有一些通用方法用於 stack 視圖。這個清單是要高亮一些有用的示例來顯示 stack 視圖的靈活性。目前這還不是一個完整的清單。

  • 只是定義位置。你可以通過固定兩個與其父視圖相鄰的邊界來定義 stack 視圖的位置。在這裡,stack 視圖的尺寸將根據其管理的視圖在兩個維度上自由擴展。當你想要 stack 視圖的內容展現其原有內容尺寸,和你想要管理其他與 stack 視圖有關聯的用戶接口元素時是特別有用的。

舉個例子,在 Figure 1中,stack 視圖的左邊界和上邊界都已經相對固定於其父視圖。這些標簽將根據帶有8個點的兩者之間的空間作為第一基線校准。這對於相對於其本身左對齊的 stack 視圖內容是有效的。

Figure 1.定義位置

blob.png

  • 定義沿著 stack 視圖軸向的尺寸。這裡,你固定了沿著 stack 視圖軸向相對於其父視圖的兩個邊界,定義了 stack 視圖沿著其軸向的尺寸。你將需要固定其他邊界中的一個來定義 stack 視圖的位置。stack 視圖將沿著其軸向改變尺寸和位置來填充定義的空間;然而,未固定的邊界將根據其管理的最大視圖的尺寸自由移動。

舉例如 Figure 2,stack 視圖的左、上、右邊界都已經相對於其父視圖固定了。使用 UIStackViewDistributionFill 分布使得其內容重設尺寸來填充它的寬度,並且從文本框有比標簽更低的內容緊湊優先級開始,它將在必要的時候被拉伸。

Figure 2.定義沿著 stack 視圖軸向的尺寸

blob.png

  • 定義垂直於 stack 視圖軸向的尺寸。這類似於上一個示例,但是你固定了垂直於 stack 視圖軸向的兩個邊界和沿著軸向的一個邊界。這使得 stack 視圖在你增加或移除其管理的視圖時將沿著其軸向擴展或回縮。除非你使用了 UIStackViewDistributionFillEqually 分布,被管理的視圖將根據其原有尺寸調節尺寸。垂直於其軸向的視圖將根據其 stack 視圖的對其模式在其定義的范圍內平鋪。

舉例,Figure 3展示了一個包含了四個標簽和一個按鈕的垂直 stack 視圖。這個 stack 視圖使用了8個點的間隙和 UIStackViewAlignmentCenter 對齊方式。stack 視圖的高度將根據 stack 內部的元素的增減而增大或回縮。

Figure 3.定義垂直於 stack 視圖軸向的尺寸

blob.png

  • 同時定義 stack 視圖的位置和尺寸。這裡你固定了 stack 視圖的所有四個邊界。stack 視圖將在提供的范圍之內平鋪其內容。舉例,Figure 4展示了一個所有四個邊界都相對於其父視圖固定的垂直 stack 視圖。通過使用 UIStackViewAlignmentCenter 對齊方式和 UIStackViewDistributionFill 分布方式,stack 視圖確保其內容將水平和垂直居中填充屏幕。然而,獲得想要的布局需要兩個額外的步驟。默認情況下,stack視圖會垂直拉伸標簽而不是圖片。要縮放圖片控件,就要降低其內容緊湊優先級到低於標簽。額外的,為了保持圖片縮放時的長寬比,你必須設置圖片視圖的模式為 Aspect Fit。增加一個圖片視圖與 stack 視圖間寬度相等約束將有助於確保圖片將被縮放來填充可用范圍。

Figure 4.同時定義 stack 視圖的位置和尺寸

blob.png

五、管理 Stack 視圖的展現

UIStackView 是 UIView 的非渲染型子類。它沒有提供其自有的任何用戶接口。相反的,它只管理被其管理的視圖的位置和尺寸。因此,有些屬性(如 backgroundColor)在 stack 視圖上是無效的。類似的,你無法重寫 layerClass,drawRect: 或 drawLayer:inContext: 方法。

這裡有一系列的屬性來定義 stack 視圖如何平鋪其內容。

  • axis(軸向) 屬性決定了 stack 的朝向,只有垂直或水平;

  • distribution(分布) 屬性決定了其管理的視圖在沿著其軸向上的布局;

  • alignment(對齊) 屬性決定了其管理的視圖在垂直於其軸向上的布局;

  • spacing(空隙) 屬性決定了其管理的視圖間的最小間隙;

  • baselineRelativeArrangement 屬性決定了其視圖間的垂直間隙是否根據基線測量得到;

  • layoutMarginsRelativeArrangement 屬性決定了 stack 視圖平鋪其管理的視圖時是否要參照它的布局邊距

通常情況下,你會使用一個 stack 視圖來布局小數量的視圖。你可以通過在其他 stack 視圖中嵌套多個 stack 視圖的方式創建更加復雜的視圖層次結構。舉例,Figure 5展示了一個包含兩個水平 stack 視圖的垂直 stack 視圖。每一個水平 stack 視圖各包含一個標簽和一個文本框。

Figure 5.Stack 視圖的嵌套

blob.png

你也可以通過增加被管理的視圖的額外約束來完美的調節一個被管理視圖的展現。舉例說明,你可以使用約束類設置視圖的最小或最大的高度或寬度。或者你可以定義一個長寬比。當平鋪其內容時,stack 視圖將使用這些約束。舉例來說,在Figure 4中,當圖片被縮放時,圖片視圖的一個長寬比約束被強行賦予了一個長寬比常數。

注意:當給一個 stack 視圖內的視圖增加約束時要特別注意避免傳入沖突。作為慣例,如果一個視圖的尺寸在一個指定的維度上默認回到其原本內容尺寸,那麼你可以安全的在這個維度上增加約束。

六、維護其管理的視圖與子視圖之間的統一性

Stack 視圖確保它的 arrangedSubviews 屬性將一直是其 subviews 屬性的子集合。明確的說,stack 視圖強制實施了以下規定:

  • 無論何時 stack 視圖增加了一個視圖到它的 arrangedSubviews 數組,其也將把這個視圖作為子視圖增加,如果還未增加的話。

  • 無論何時一個子視圖從 stack 視圖中被移除,那麼 stack 視圖也將將其從 arrangedSubviews 數組中移除。

  • 從 arrangedSubviews 移除一個視圖並不會將其作為子視圖移除。stack 視圖將不再管理該視圖的尺寸和位置,但是該視圖仍將是視圖結構的一部分,並且當其可見的情況下仍會被渲染到屏幕上。

當 arrangedSubviews 數組一直包含著 subviews 數組的子集合,這些數組間的順序仍然是獨立的。

  • arrangedSubviews 數組的順序定義了展現在 stack 中的視圖的順序。對於水平 stack 視圖,這些視圖將以閱讀順序平鋪,即較小索引的視圖在較大索引視圖的左側。對於垂直 stack 視圖,這些視圖是從上到下平鋪的,及較小索引的視圖在較大索引視圖的上方。

  • subviews 數組中的順序定義了子視圖在Z軸上是順序。如果視圖重疊,有較小索引的子視圖將出現在有較大索引的子視圖後方。

七、動態改變 Stack 視圖內容

當視圖被加入、移出或插入 arrangedSubviews 數組時,或當一個被管理的子視圖的 hidden 屬性改變時,stack 視圖都會自動更新它的布局。

OC代碼如下:

// Appears to remove the first arranged view from the stack.
// The view is still inside the stack, it's just no longer visible, and no longer contributes to the layout.
UIView * firstView = self.stackView.arrangedSubviews[0];
firstView.hidden = YES;

Swift代碼如下:

// Appears to remove the first arranged view from the stack.
// The view is still inside the stack, it's just no longer visible, and no longer contributes to the layout.
let firstView = stackView.arrangedSubviews[0]
firstView.hidden = true

stack 視圖也會自動響應其任何屬性的改變。舉例,你可以更新 stack 視圖的 axis 屬性來動態改變的朝向。

OC代碼如下:

// Toggle between a vertical and horizontal stack
if (self.stackView.axis == UILayoutConstraintAxisHorizontal) {
    self.stackView.axis = UILayoutConstraintAxisVertical;
}else {
    self.stackView.axis = UILayoutConstraintAxisHorizontal;
}

Swift代碼如下:

// Toggle between a vertical and horizontal stack
if stackView.axis == .Horizontal {
    stackView.axis = .Vertical
}else {
    stackView.axis = .Horizontal
}

對於被管理的子視圖的 hidden 屬性的變化和 stack 視圖屬性的變化,你可以通過將這些改變內置到一個動畫塊代碼的方式以動畫方式展現。

OC代碼如下:

// Animates removing the first item in the stack.
[UIView animateWithDuration:0.25 animations:^{
    UIView * firstView = self.stackView.arrangedSubviews[0];
    firstView.hidden = YES;
}];

Swift代碼如下:

// Animates removing the first item in the stack.
UIView.animateWithDuration(0.25) { () -> Void in
    let firstView = stackView.arrangedSubviews[0]
    firstView.hidden = true}

最後,你可以直接在Interface Builder中給很多 stack 視圖屬性定義特定的 “尺寸類” 類型值。系統將在 stack 視圖的尺寸類改變時動畫展現這些改變。

八、常用的方法

創建 Stack 視圖

- initWithArrangedSubviews:  (New in iOS 9.0)

管理安排的子視圖

- addArrangedSubview: (New in iOS 9.0)
  arrangedSubviews Property (New in iOS 9.0)
- insertArrangedSubview:atIndex: (New in iOS 9.0)
- removeArrangedSubview: (New in iOS 9.0)

設置布局

alignment Property  (New in iOS 9.0)
axis Property  (New in iOS 9.0)
baselineRelativeArrangement Property  (New in iOS 9.0)
distribution Property  (New in iOS 9.0)
layoutMarginsRelativeArrangement Property  (New in iOS 9.0)
spacing Property  (New in iOS 9.0)

常量

UIStackViewDistribution
UIStackViewAlignment

本文原文及圖片來源:UIStackView Class Reference

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved