UIStackView 初探(譯)

UIStackView

用于在列或行中布局視圖集合的線性接口。

UIStackView 概覽

UIStackView 允許您利用自動(dòng)布局的強(qiáng)大功能,創(chuàng)建能夠動(dòng)態(tài)適應(yīng)設(shè)備方向、屏幕大小和可用空間中的任何更改的用戶界面。UIStackView 在其 arrangedSubviews 屬性中管理所有視圖的布局。這些視圖根據(jù)在 arrangedSubviews 數(shù)組中的順序沿著視圖棧主軸排列。視圖精確的布局依賴于 UIStackView 的 axis、distribution、alignment、spacing以及其他屬性的共同作用。


WechatIMG390.jpeg

要使用 UIStackView,請(qǐng)打開您希望編輯的 Storyboard。從對(duì)象庫(kù)中拖動(dòng) Horizontal Stack View(水平棧)或Vertical Stack View(垂直棧),并將堆棧視圖定位到需要的位置。接下來(lái),拖出棧的內(nèi)容,將視圖或控件拖放到棧中。您可以根據(jù)需要繼續(xù)向棧添加視圖和控件。Interface Builder 根據(jù)棧的內(nèi)容調(diào)整棧的大小。您還可以通過(guò)在屬性檢查器中修改 UIStackView 圖的屬性來(lái)調(diào)整棧內(nèi)容的外觀。

note:開發(fā)者負(fù)責(zé)定義 UIStackView 的位置和大小(可選)。然后,UIStackView 管理其內(nèi)容的布局和大小。

UIStackView 與自動(dòng)布局

堆棧視圖使用自動(dòng)布局來(lái)定位和調(diào)整其排列的視圖的大小。堆棧視圖將第一個(gè)和最后一個(gè)被安排的視圖與其沿堆棧軸的邊緣對(duì)齊。在水平堆棧中,這意味著第一個(gè)排列的視圖的前緣被固定在棧的左邊緣,而最后一個(gè)排列的視圖的后緣被固定在堆棧的右邊緣。在垂直棧中,頂部和底部邊緣分別固定在棧的頂部和底部邊緣上。如果將 UIStackView 的 isLayoutMarginsRelativeArrangement 屬性設(shè)置為 true,那么堆棧視圖將其內(nèi)容固定到相關(guān)的邊距而不是邊緣。

除了 UIStackView.Distribution.FillEquality分布,則堆棧視圖在沿堆棧軸計(jì)算其大小時(shí)使用每個(gè)排列視圖的intrinsicContentSize屬性。UIStackView.Distribution.FillEquality調(diào)整所有排列視圖的大小,使其大小相同,沿視圖棧的軸填充棧視圖。如果可以,UIStackView 會(huì)拉伸所有排列的視圖,以匹配沿棧軸具有最長(zhǎng)內(nèi)部大小的視圖。

對(duì)于除 UIStackView.Alignment.fill 對(duì)齊時(shí),UIStackView 在計(jì)算垂直于棧軸的大小時(shí)使用每個(gè)排列視圖的 intrinsicContentSize 屬性。UIStackView.Alignment.fill 調(diào)整所有排列視圖的大小,以便它們垂直于堆棧視圖的軸填充堆棧視圖。如果可以,堆棧視圖將拉伸所有排列的視圖,以與垂直于堆棧軸的最大內(nèi)在尺寸的視圖匹配。


WechatIMG391.jpeg

動(dòng)態(tài)改變棧視圖的位置和尺寸

盡管 UIStackView 允許您在不直接使用自動(dòng)布局的情況下布局其內(nèi)容,但仍然需要使用自動(dòng)布局來(lái)定位 UIStackView 本身。一般來(lái)說(shuō),這意味著固定 UIStackView 的至少兩個(gè)相鄰邊,以定義其位置。在沒有附加約束的情況下,系統(tǒng)根據(jù) UIStackView 的內(nèi)容計(jì)算其大小。

  • 沿著 UIStackView 的軸,它的大小等于已排列的視圖大小加上視圖間的空間總和。
  • UIStackView 軸的垂直方向,它的大小等于最大的已布局視圖的尺寸
  • 如果 UIStackView 的 isLayoutMarginsRelativeArrangement 屬性設(shè)置為true,那么它的大小增加已包含邊緣空白的空間。

可以提供其他約束來(lái)指定 UIStackView 的高度、寬度或兩者。在這些情況下,堆棧視圖將調(diào)整其排列視圖的布局和大小,以填充指定區(qū)域。確切的布局因堆棧視圖的屬性而異。見 UIStackView.Distribution 以及 UIStackView.Alignment 枚舉以獲取有關(guān) UIStackView 如何處理其內(nèi)容具有額外空間或空間不足的完整描述。
也可以根據(jù) UIStackView 的第一個(gè)或最后一個(gè)基線來(lái)定位 UIStackView,而不是使用頂部、底部或中心Y位置。與 UIStackView 的擬合大小一樣,這些基線是根據(jù) UIStackView 的內(nèi)容計(jì)算的。

  • 水平 UIStackView 返回forFirstBaselineLayout和forLastBaselineLayout方法的最高視圖。如果最高的視圖也是 UIStackView,則返回對(duì)嵌套 UIStackView 調(diào)用forFirstBaselineLayout或forLastBaselineLayout的結(jié)果。

  • 垂直 UIStackView 返回forFirstBaselineLayout的第一個(gè)排列視圖和forLastBaselineLayout的最后一個(gè)排列視圖。如果這些視圖中的任何一個(gè)也是UIStackView,那么它將返回對(duì)嵌套 UIStackView 調(diào)用forFirstBaselineLayout或forLastBaselineLayout的結(jié)果。

note:基線對(duì)齊僅適用于高度與其內(nèi)部?jī)?nèi)容大小高度匹配的視圖。如果視圖被拉伸或壓縮,基線顯示在錯(cuò)誤的位置。

管理 UIStackView 的外觀

UIStackView 管理其排列視圖的大小和位置。有許多屬性定義 UIStackView 如何布局其內(nèi)容

  • axis 屬性決定棧的方向,無(wú)論是垂直方向還是水平方向
  • distribution 屬性決定沿著棧的軸排列的視圖的布局
  • alignment 屬性確定垂直于堆棧軸的排列視圖的布局。
  • spacing 屬性決定排列視圖間的最小空間。
  • isBaselineRelativeArrangement 屬性確定是否從基線測(cè)量視圖之間的垂直間距。
  • isLayoutMarginsRelativeRangement 屬性確定UIStackView是否相對(duì)于其布局頁(yè)邊距布局其排列視圖。

通常,您使用單個(gè) UIStackView 來(lái)布局少量的項(xiàng)。通過(guò)將 UIStackView 嵌套在其他 UIStackView 中,可以構(gòu)建更復(fù)雜的視圖層次結(jié)構(gòu)。如下圖顯示了一個(gè)包含兩個(gè)水平堆棧視圖的垂直堆棧視圖。每個(gè)水平堆棧視圖都包含一個(gè)標(biāo)簽和一個(gè)文本字段。


WechatIMG392.jpeg

也可以通過(guò)向排列視圖添加其他約束來(lái)微調(diào)排列視圖的外觀。例如,可以使用約束設(shè)置視圖的最小或最大高度或?qū)挾?。也可以為視圖定義縱橫比。布局其內(nèi)容時(shí)使用這些約束。例如,在圖像視圖中有一個(gè)寬高比約束,該約束在調(diào)整圖像大小時(shí)強(qiáng)制執(zhí)行恒定的縱橫比。

在向堆棧視圖中的視圖添加約束時(shí),請(qǐng)小心避免引入沖突。一般來(lái)說(shuō),如果視圖的大小默認(rèn)為給定維度的內(nèi)部?jī)?nèi)容大小,則可以安全地為該維度添加約束。

動(dòng)態(tài)改變 UIStackView 的內(nèi)容

當(dāng)對(duì)arrangedSubviews 數(shù)組內(nèi)容進(jìn)行增加、刪除、插入,或者改變 排列視圖的子視圖的 isHidden 屬性時(shí),UIStackView 將自動(dòng)跟新它的布局

// 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.isHidden = true

UIStackView 還自動(dòng)響應(yīng)對(duì)其任何屬性的更改。例如,可以通過(guò)更新堆棧視圖的axis屬性來(lái)動(dòng)態(tài)更改堆棧的方向。

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

通過(guò)將這些更改放置在動(dòng)畫塊中,可以設(shè)置對(duì)已排列子視圖的isHidden屬性的更改和對(duì) UIStackView 屬性的更改的動(dòng)畫。

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

最后,您可以直接在I nterface Builder中為 UIStackView 的許多屬性定義特定于大小類的值。每當(dāng)堆棧視圖的大小類更改時(shí),系統(tǒng)會(huì)自動(dòng)設(shè)置這些更改的動(dòng)畫。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容