UIStackView文檔翻譯

前段時(shí)間有空,回顧一下知識(shí)點(diǎn)。就去官網(wǎng)看了一下UIStackView的文檔,掃一下知識(shí)盲區(qū)。以下為翻譯:

UIStackView
一種流式布局,管理橫向或者縱向的視圖集合。繼承于UIView。

概述:
Stack view 讓你使用強(qiáng)大的自動(dòng)布局,創(chuàng)建能夠自動(dòng)適配設(shè)備任何方向,大小,和各個(gè)屏幕尺寸空間的用戶(hù)視圖。Stack view管理ArrangedSubviews屬性中的所有視圖布局。這些視圖按照ArrangedSubviews的順序,沿著stack view的軸進(jìn)行排列。實(shí)際的布局取決于stack view的軸(Axis)、分布(Distribution)、對(duì)齊(Alignment)、間距(Spacing)和其他屬性。


圖一.png

打開(kāi)StoryBoard使用stack view。從控件對(duì)象庫(kù)中,拖動(dòng)任意一個(gè)水平或者垂直的Stack View,放到需要的位置。然后拖動(dòng)視圖或者控制器,放到StackView中。如果有必要,還可以放多個(gè)視圖或者控制器。IB會(huì)根據(jù)StackView的視圖內(nèi)容來(lái)重新計(jì)算StackView的大小。你也能夠通過(guò)調(diào)整StackView的屬性來(lái)控制子視圖的外觀大小。
注意:你要約束好StackView的位置和大小(可選)。StackView才能管理好子視圖的布局和大小。

StackView和自動(dòng)布局
StackView使用自動(dòng)布局來(lái)對(duì)子視圖調(diào)整位置和大小。將第一個(gè)子視圖和最后一個(gè)子視圖沿著StackView的軸進(jìn)行邊緣對(duì)齊排列。在水平的StackView中,第一個(gè)子視圖的左邊距固定在StackView的左邊,最后一個(gè)子視圖的右邊距固定在StackView的右邊。相同的,在垂直的StackView中,子視圖的上下邊距分別對(duì)應(yīng)StackView的上下邊距。如果設(shè)置StackView的layoutMarginsRelativeArrangement屬性為YES,StackView的子視圖布局就不是固定到StackView的邊距,而是使用設(shè)置的相關(guān)邊距。

除了UIStackViewDistributionFillEqually屬性外的分布(Distribution)屬性,子視圖都是按照自身的大小,按照StackView的軸進(jìn)行排列。但是UIStackViewDistributionFillEqually屬性,就會(huì)將StackView軸方向的寬度平分給子視圖,讓子視圖重新計(jì)算大小,填滿(mǎn)整個(gè)StackView的軸方向。如果可以,StackView也會(huì)按照子視圖中最大的一個(gè)寬度,強(qiáng)制拉伸所有的子視圖到最大的寬度。

除了 UIStackViewAlignmentFill屬性外的對(duì)齊(Alignment)屬性,子視圖都是按照自身的大小,來(lái)填充子視圖垂直于StackView方向軸的寬度大小。而 UIStackViewAlignmentFill屬性,會(huì)重新計(jì)算子視圖來(lái)填充滿(mǎn)StackView垂直于軸方向的寬度。如果可能,StackView會(huì)用子視圖垂直stack軸方向的最大寬度為標(biāo)準(zhǔn),拉伸其他子視圖,用來(lái)填滿(mǎn)垂直于stack方向軸的寬度。(emmmmmmmm,垂直于軸方向的,直譯起來(lái)別扭,但是又找不到很好的形容詞。什么是垂直于軸方向呢,就是如果StackView是垂直的,垂直于StackView軸方向就是水平,這個(gè)水平可以理解成視圖的寬度,此時(shí)子視圖的寬度要填充滿(mǎn)StackView的寬度)

圖二.png

StackView的位置和大小
即使StackView允許子視圖不直接使用自動(dòng)布局而直接添加,但是StackView自身也需要用自動(dòng)布局。這就意味著至少需要兩個(gè)相鄰邊距,用來(lái)調(diào)整StackView的邊距并確定位置。不需要額外的約束,系統(tǒng)就會(huì)根據(jù)StackView的子視圖內(nèi)容來(lái)自動(dòng)計(jì)算出StackView的大小。

1、沿著StackView的軸方向,計(jì)算其軸方向?qū)挾鹊姆椒?,是所有子視圖寬度的總和加上,每個(gè)子視圖之間的間距總和。即StackView軸方向?qū)挾?子視圖寬度總和+子視圖間距總和。

2、垂直于StackView軸方向,它的寬度以子視圖中一個(gè)最大寬度的子視圖為準(zhǔn)。

3、如果StackView的layoutMarginsRelativeArrangement屬性為YES。則StackView的大小,就是按照子視圖各自的大小和約束邊距逐個(gè)相加。因?yàn)樽右晥D的大小不受StackView的屬性約束。

你也可以為StackView本身添加寬度和高度約束。這樣的話(huà),StackView就會(huì)調(diào)整子視圖的布局和大小,用來(lái)填充滿(mǎn)StackView的區(qū)域。子視圖的準(zhǔn)確布局,依賴(lài)于StackView的屬性。如果遇到StackView內(nèi)容空間不足或者填不滿(mǎn)的情況,請(qǐng)參閱UIStackViewDistributionUIStackViewAlignment枚舉說(shuō)明。

你可以使用第一條或者最后一條基線(xiàn)來(lái)定位一個(gè)StackView,而不使用頂部,底部,Y軸中心店對(duì)齊的方式來(lái)定位。比如StackView處理大小,他的基線(xiàn)是依靠StackView的內(nèi)容來(lái)計(jì)算的。

水平的StackView,返回一個(gè)最高層級(jí)視圖的viewForFirstBaselineLayoutviewForLastBaselineLayout方法。如果最高層級(jí)的視圖也是一個(gè)StackView,那么他返回的結(jié)果,就是這個(gè)StackView的viewForFirstBaselineLayout or viewForLastBaselineLayout 方法。

垂直的StackView,返回的是第一個(gè)子視圖的viewForFirstBaselineLayout和最后一個(gè)子視圖的viewForLastBaselineLayout。如果第一個(gè)或者最后一個(gè)之中,有一個(gè)是SatckView,那么這個(gè)結(jié)果就是使用這個(gè)StackView的viewForFirstBaselineLayout 或者 viewForLastBaselineLayout。

注意:
基線(xiàn)對(duì)齊僅適用于,子視圖高度和StackView的高度匹配的情況。如果子視圖過(guò)大或者太小,基線(xiàn)就會(huì)錯(cuò)誤的定位。

常見(jiàn)的幾個(gè)StackView布局
以下是常見(jiàn)的,使用StackView為視圖內(nèi)容布局的案例。
1、僅僅定義位置。通過(guò)調(diào)整與父視圖的兩個(gè)邊距,來(lái)確定StackView的位置。例如,StackView的大小依賴(lài)于子視圖的寬高。這個(gè)方法適用于,添加視圖后,視圖的排列不亂,且StackView的大小適應(yīng)內(nèi)容視圖大小。
如下圖:通過(guò)固定與父視圖的上邊距和左邊距來(lái)展示StackView。兩個(gè)label對(duì)齊StackView布局,中間間距為8pt,左對(duì)齊StackView。


圖三.png

2、沿著軸來(lái)確定StackView的大小。例如,沿著StackView的軸方向固定兩個(gè)與父視圖的邊距,確定好SatckView的大小。你也需要固定另外一個(gè)邊距,來(lái)確定StackView的位置。StackView的大小和位置,就取決于內(nèi)容沿著軸方向去填滿(mǎn)的寬度,包括子視圖的間距。然而,那個(gè)不確定的間距就取決于最大的子視圖的大小。

如下圖:


圖四.png

3、確定好垂直StackView軸方向的大小。這個(gè)與上一個(gè)例子類(lèi)似,但是你要固定垂直于軸方向的邊距,并且固定軸方向的一個(gè)邊距。StackView的軸方向大小就會(huì)隨著你添加子視圖而增長(zhǎng)或壓縮。除非使用fill Equally 屬性,否則StackView的大小,就等于所有子視圖自己固有的大小總和。垂直于其軸方向,子視圖就會(huì)隨著StackView的對(duì)應(yīng)的對(duì)齊方式,布局好自己的位置。

如下圖:展示了垂直的SatckView,里面有四個(gè)label和一個(gè)button。StackView使用了8pt的間距以及居中對(duì)齊的對(duì)齊方式。StackView的高度,也會(huì)隨著子視圖的添加和移除,而變大和縮小。


圖五.png

4、定義好位置和大小的StackView。比如,定義好了StackView的四個(gè)邊距,其子視圖就只能在限制的空間內(nèi)布局。

如下圖,展示了一個(gè)定義好四個(gè)邊距的StackView。使用了劇中布局的對(duì)齊方式和填充滿(mǎn)的屬性。StackView讓子視圖在正中心布局填充滿(mǎn)整個(gè)SatckView。然而,想要達(dá)到這種布局,還需要額外的幾個(gè)步驟。默認(rèn)的,在StackView的垂直方向中,會(huì)拉伸UILabel而不會(huì)拉伸UIImageView。要調(diào)增ImageView,使UILabel的內(nèi)容擁抱優(yōu)先級(jí)低于UIImageView。另外,UIImageView會(huì)設(shè)置Aspect Fit的填充方式,來(lái)維持ImageView的展示比例,以防止圖片失真。對(duì)UIImageView和StackView添加一個(gè)等寬約束,會(huì)有助于ImageView在有效的空間里,展示ImageView。


圖六.png

管理StackView的外觀
UIStackView是UIView的非呈現(xiàn)子類(lèi)。因此,它不會(huì)提供任何的用戶(hù)操作接口。但是它可以直接自動(dòng)管理子視圖的位置和大小。結(jié)果是,一些屬性(比如backgroundColor)在StackView沒(méi)有效果。同樣的,不能重寫(xiě)layerClass, drawRect:, or drawLayer:inContext:等方法。

下面有幾個(gè)如何定義StackView內(nèi)容布局的屬性:

1、axis屬性,定義SatckView的布局方向,垂直或者是水平。

2、distribution屬性,確定子視圖軸方向的布局。

3、alignment屬性,確定子視圖垂直于軸方向的布局。

4、spacing屬性,確定兩個(gè)子視圖之間的最小間距。

5、 baselineRelativeArrangement屬性,確定是否從基線(xiàn),來(lái)測(cè)量子視圖之間的垂直距離。

6、 layoutMarginsRelativeArrangement屬性,確定StackView是否相對(duì)于其布局邊距來(lái)布置其排列的子視圖。

通常,大家會(huì)使用一個(gè)StackView來(lái)布局幾個(gè)少量的子視圖。但是你也可以使用嵌套的StackView來(lái)復(fù)雜的視圖。例如下圖,展示了一個(gè)垂直StackView包含兩個(gè)水平布局的StackView。每一個(gè)水平的StackView包含有一個(gè)UILabel和一個(gè)UITextFiled。


圖七.png

你也能夠通過(guò)給子視圖添加額外的約束,來(lái)調(diào)整子視圖的外觀。比如,你能使用約束來(lái)設(shè)置視圖的最大或最小的寬高。或者你能夠設(shè)置視圖的寬高比。當(dāng)子視圖布局的時(shí)候,UIStackView會(huì)使用這些約束。比如,UIImageView有一個(gè)寬高比,在image重新布局時(shí),可以使用寬高比強(qiáng)制約束。

注意:
在為UIStackView中的子視圖添加約束是,要小心避免約束引用沖突。一般來(lái)說(shuō),如果一個(gè)視圖返回的默認(rèn)大小,是內(nèi)容給定的尺寸大小,那么你就可以為這個(gè)尺寸安全的添加約束。

維護(hù)ArrangedViews和SubViews的一致性
StackView會(huì)確保,arrangedSubviews屬性是subviews屬性的子集。以下幾點(diǎn),是StackView必須遵守的規(guī)則:

1、StackView添加了視圖到ArrangedViews的同時(shí),也會(huì)添加到SubViews中。
2、當(dāng)子視圖從StackView中移除時(shí),StackView也會(huì)將其從ArrangedViews中移除。
3、從ArrangedViews中移除,不一定會(huì)從SubViews中移除。而且StackView不再會(huì)管理視圖的大小和位置,但是視圖仍然在StackView中,在需要的時(shí)候也會(huì)被渲染,出現(xiàn)在屏幕上。

即使ArrangedSubViews數(shù)組總是SubViews的子集,但是他自己的數(shù)組順序也是保持獨(dú)立的。
1、arrangedViews數(shù)組的順序,在視圖出現(xiàn)在StackView中的時(shí)候被確定。對(duì)于水平StackView來(lái)說(shuō),子視圖會(huì)按照順序布局,低索引的排在高索引之前。正常來(lái)說(shuō),它會(huì)從左到右依次排列。在垂直的StackView中,視圖會(huì)從高到低,按照索引依次排列。
2、subViews的順序定義了subViews的Z軸順序。如果子視圖重疊,視圖就會(huì)按照誰(shuí)索引低的在索引高的上面來(lái)進(jìn)行排列。

動(dòng)態(tài)修改StackView的內(nèi)容視圖
當(dāng)子視圖被添加、移除、插入到ArrangedSubViews數(shù)組中,或者ArrangedSiubViews中的子視圖hidden屬性被改變時(shí),StackView會(huì)自動(dòng)更新布局。

如果StackView的任意一個(gè)屬性被改變,StackView也會(huì)自動(dòng)響應(yīng)的作出改變。比如,你可以通過(guò)修改axis屬性,來(lái)動(dòng)態(tài)修改StackView的方向。

你可以將arrangedSubViews的hidden屬性修改和StackView的屬性修改,這兩個(gè)方法,放到動(dòng)畫(huà)的方法塊中,讓這兩個(gè)改變產(chǎn)生動(dòng)畫(huà)。

最后,你能夠在IB中,為StackView許多的屬性添加大小類(lèi)的特定值。系統(tǒng)會(huì)在這些大小類(lèi)被改變時(shí),自動(dòng)添加動(dòng)畫(huà)。

?著作權(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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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