UIKit框架(二十一) —— UIStackView的使用(一)

版本記錄

版本號(hào) 時(shí)間
V1.0 2019.07.05 星期五

前言

iOS中有關(guān)視圖控件用戶能看到的都在UIKit框架里面,用戶交互也是通過(guò)UIKit進(jìn)行的。感興趣的參考上面幾篇文章。
1. UIKit框架(一) —— UIKit動(dòng)力學(xué)和移動(dòng)效果(一)
2. UIKit框架(二) —— UIKit動(dòng)力學(xué)和移動(dòng)效果(二)
3. UIKit框架(三) —— UICollectionViewCell的擴(kuò)張效果的實(shí)現(xiàn)(一)
4. UIKit框架(四) —— UICollectionViewCell的擴(kuò)張效果的實(shí)現(xiàn)(二)
5. UIKit框架(五) —— 自定義控件:可重復(fù)使用的滑塊(一)
6. UIKit框架(六) —— 自定義控件:可重復(fù)使用的滑塊(二)
7. UIKit框架(七) —— 動(dòng)態(tài)尺寸UITableViewCell的實(shí)現(xiàn)(一)
8. UIKit框架(八) —— 動(dòng)態(tài)尺寸UITableViewCell的實(shí)現(xiàn)(二)
9. UIKit框架(九) —— UICollectionView的數(shù)據(jù)異步預(yù)加載(一)
10. UIKit框架(十) —— UICollectionView的數(shù)據(jù)異步預(yù)加載(二)
11. UIKit框架(十一) —— UICollectionView的重用、選擇和重排序(一)
12. UIKit框架(十二) —— UICollectionView的重用、選擇和重排序(二)
13. UIKit框架(十三) —— 如何創(chuàng)建自己的側(cè)滑式面板導(dǎo)航(一)
14. UIKit框架(十四) —— 如何創(chuàng)建自己的側(cè)滑式面板導(dǎo)航(二)
15. UIKit框架(十五) —— 基于自定義UICollectionViewLayout布局的簡(jiǎn)單示例(一)
16. UIKit框架(十六) —— 基于自定義UICollectionViewLayout布局的簡(jiǎn)單示例(二)
17. UIKit框架(十七) —— 基于自定義UICollectionViewLayout布局的簡(jiǎn)單示例(三)
18. UIKit框架(十八) —— 基于CALayer屬性的一種3D邊欄動(dòng)畫的實(shí)現(xiàn)(一)
19. UIKit框架(十九) —— 基于CALayer屬性的一種3D邊欄動(dòng)畫的實(shí)現(xiàn)(二)
20. UIKit框架(二十) —— 基于UILabel跑馬燈類似效果的實(shí)現(xiàn)(一)

開(kāi)始

首先看下寫作環(huán)境

Swift 5, iOS 12, Xcode 10

主要內(nèi)容:了解如何使用UIStackView簡(jiǎn)化iOS布局。 使用對(duì)齊,分布和間距水平或垂直布局一系列視圖。

您是否曾經(jīng)需要在運(yùn)行時(shí)添加或刪除視圖中的視圖并調(diào)整旁邊的視圖布局? 也許您調(diào)整了一些約束或使用第三方庫(kù)來(lái)完成這項(xiàng)工作。 也許它不是運(yùn)行時(shí)的東西,而是你希望在故事板中的其他視圖之間插入一個(gè)新視圖。

在這些情況下,您需要更改多個(gè)約束。 您可能會(huì)發(fā)現(xiàn)自己刪除了該區(qū)域中的所有約束并重新添加它們。

UIStackView簡(jiǎn)化了這些任務(wù)。 您可以在堆棧視圖中輕松地水平或垂直布局一系列視圖,并使用諸如對(duì)齊,分布和間距等屬性將視圖自動(dòng)調(diào)整到可用空間的方式進(jìn)行設(shè)置。 請(qǐng)享用!

打開(kāi)準(zhǔn)備好的項(xiàng)目材料。 使用iPhone 8 Simulator在Xcode中構(gòu)建并運(yùn)行啟動(dòng)項(xiàng)目。 你會(huì)看到以下內(nèi)容:

這是Vacation Spots應(yīng)用程序。 它建議了一系列可以遠(yuǎn)離它的地方。 在去任何地方之前,您將使用Stack Views解決應(yīng)用程序的一些問(wèn)題。

1. Exploring Vacation Spots

點(diǎn)擊London,進(jìn)入倫敦的信息視圖。 乍一看,視圖可能看起來(lái)不錯(cuò),但它有一些問(wèn)題:

  • 1) 查看視圖底部的按鈕行。 由于它們之間的固定間距,它們不適應(yīng)屏幕寬度。 要更好地查看問(wèn)題,請(qǐng)按Command-left箭頭將模擬器旋轉(zhuǎn)到橫向。
  • 2) 點(diǎn)擊WEATHER旁邊的Hide。 這會(huì)隱藏文本,但它不會(huì)重新布局它下面的部分,留下一塊空白區(qū)域。
  • 3) 區(qū)域內(nèi)容需要改進(jìn)。 如果在WHY VISIT之后出現(xiàn)了WHAT TO SEE,而不是在它們之間定位天氣部分,那將更符合邏輯。
  • 4) 在橫向模式下,底行按鈕太靠近視圖的下邊緣。 如果減小section之間的間距,它看起來(lái)會(huì)更好 - 但僅限于橫向模式。

現(xiàn)在您已經(jīng)了解了將要進(jìn)行的改進(jìn),現(xiàn)在是時(shí)候深入了解該項(xiàng)目。 打開(kāi)Main.storyboard。 它將以初始設(shè)備視圖打開(kāi)。 確保它將iPhone 8顯示為所選設(shè)備。

這在運(yùn)行時(shí)沒(méi)有任何影響,但可以幫助您了解屏幕在該設(shè)備上的外觀。 您可以通過(guò)單擊其他圖標(biāo)隨時(shí)更改所選設(shè)備。 將鼠標(biāo)懸停在圖標(biāo)上可顯示其相應(yīng)的設(shè)備。

注意:如果減小Interface Builder畫布寬度(大約低于650像素),則更改設(shè)備的UI會(huì)稍微改變。 設(shè)備列表折疊為Device下拉列表:

當(dāng)按下時(shí),它會(huì)顯示垂直布局的可用設(shè)備列表:

現(xiàn)在,仔細(xì)查看Spot Info View Controller

你可能想知道顏色是什么?

這些標(biāo)簽和按鈕具有不會(huì)在運(yùn)行時(shí)顯示的背景顏色。 在故事板中,它們是視覺(jué)輔助工具,可幫助顯示更改堆棧視圖的各種屬性如何影響其嵌入視圖的框架。

如果在運(yùn)行應(yīng)用程序時(shí)您想在任何時(shí)候查看背景顏色,您可以在SpotInfoViewController內(nèi)的viewDidLoad()中臨時(shí)注釋掉以下行。

// Clear background colors from labels and buttons
for view in backgroundColoredViews {
  view.backgroundColor = UIColor.clear
}

任何outlet連接的label都有一個(gè)與outlet變量名稱匹配的占位符文本。 這樣可以更容易地確定哪些標(biāo)簽將在運(yùn)行時(shí)更新其文本。 例如,帶有文本<whyVisitLabel>的標(biāo)簽連接到:

@IBOutlet var whyVisitLabel: UILabel!

是時(shí)候開(kāi)始了!


Your First Stack View

首先,您將修復(fù)底行按鈕之間的間距。 堆棧視圖可以以各種方式沿其軸分布其子視圖。 一種方法是在每個(gè)視圖之間設(shè)置相等的間距。

幸運(yùn)的是,將現(xiàn)有視圖嵌入到新的stack view中是件小事。 首先,單擊Spot Info View Controller場(chǎng)景底部的所有按鈕,然后單擊其中一個(gè)按鈕,然后command-clicking其他兩個(gè)按鈕。 使用故事板畫布左下角的Show Document Outline按鈕打開(kāi)大綱視圖。

確認(rèn)您已選擇所有三個(gè)按鈕。

它們?cè)诖缶V視圖中突出顯示。 您還可以command-click大綱視圖中的每個(gè)按鈕以選擇它們。

選擇后,單擊故事板畫布右下角的Auto Layout工具欄中的Embed In按鈕。 將出現(xiàn)一個(gè)包含可用嵌入選項(xiàng)的菜單。 選擇堆棧視圖:

Xcode會(huì)將按鈕嵌入到新的堆棧視圖中。

1. Stack View Constraints

雖然堆棧視圖負(fù)責(zé)定位按鈕,但仍需要添加自動(dòng)布局約束來(lái)定位堆棧視圖本身。

在堆棧視圖中嵌入視圖時(shí),它會(huì)丟失對(duì)其他視圖的約束。 例如,在將按鈕嵌入堆棧視圖之前,Submit Rating按鈕的頂部在RATING標(biāo)簽的底部有一個(gè)垂直間距約束:

選擇Submit Rating按鈕并驗(yàn)證它是否不再附加任何約束:

您還可以查看Size inspector (Option-Command-5)以驗(yàn)證沒(méi)有約束:

有時(shí),在擁擠的故事板的視圖控制器中選擇特定元素很困難。 您可以從outline view中選擇元素,或使用Shift并右鍵單擊或按住Control鍵并單擊要選擇的視圖。 這將為您提供一個(gè)上下文菜單,顯示您單擊的位置的視圖層次結(jié)構(gòu)。 在菜單中單擊選擇stack view

現(xiàn)在您已選擇Stack View,您可以為其添加約束。

單擊Auto Layout工具欄中的Add New Constraints按鈕以顯示Add New Constraints彈出窗口。

首先,為Constrain to margins添加一個(gè)選中。 然后,將以下約束添加到堆棧視圖的邊緣:

Top: 20, Leading: 0, Trailing: 0, Bottom: 0

仔細(xì)檢查top, leading, trailing, and bottom約束的數(shù)字。 確保已打開(kāi)四個(gè)紅色I-beamsConstrain to margins。 然后,單擊Add 4 Constraints

現(xiàn)在堆棧視圖的大小正確,但它已拉伸第一個(gè)按鈕以填充任何額外空間。

2. Stack View Appearance

確定堆棧視圖如何沿其軸布置其子視圖的屬性是分布。 目前,它設(shè)置為Fill,這意味著子視圖將沿其軸完全填充堆棧視圖。 要實(shí)現(xiàn)此目的,堆棧視圖將僅展開(kāi)其子視圖之一以填充該額外空間。 具體來(lái)說(shuō),它對(duì)最低的horizontal content hugging priority的視圖進(jìn)行擴(kuò)展,或者如果所有優(yōu)先級(jí)相等,則擴(kuò)展第一個(gè)視圖。

但是,您不希望按鈕完全填充堆棧視圖 - 您希望它們間隔相等。

確保仍然選中堆棧視圖并轉(zhuǎn)到Attributes inspector檢查器。 將DistributionFill更改為Equal Spacing

現(xiàn)在構(gòu)建并運(yùn)行,點(diǎn)擊任何單元格,然后旋轉(zhuǎn)模擬器。 您會(huì)看到底部按鈕現(xiàn)在可以平等分配!

實(shí)現(xiàn)UI時(shí),請(qǐng)始終詢問(wèn)自己元素是否適合可用空間。

以下是您的內(nèi)容如何影響用戶體驗(yàn)的示例:將Wikipedia按鈕的標(biāo)題更改為Wikipedia website并運(yùn)行該應(yīng)用程序。 將模擬器從縱向旋轉(zhuǎn)到橫向以查看差異。

在空間更緊湊的縱向方向上,最后一個(gè)按鈕中的文本被剪裁,而在橫屏中一切都很合適。

這是您經(jīng)常遇到的問(wèn)題,尤其是iPhone SE等較窄的屏幕尺寸。

幸運(yùn)的是,這是一個(gè)簡(jiǎn)單的解決方案。 在仍然選擇堆棧視圖的情況下,返回Attributes inspector。 將比例從Equal Spacing更改為Fill Proportionally并將間距值更改為10

現(xiàn)在,構(gòu)建并運(yùn)行并檢查兩個(gè)方向。 你會(huì)發(fā)現(xiàn)一切都好了。

將按鈕的名稱更改回Wikipedia。

恭喜,您已經(jīng)構(gòu)建了第一個(gè)堆棧視圖!

3. Without a Stack View

為了在沒(méi)有堆棧視圖的情況下解決此間距問(wèn)題,您必須在每對(duì)按鈕之間使用一個(gè)間隔視圖,為所有間隔視圖添加相等的寬度約束,以及正確定位間隔視圖的若干附加約束。

這看起來(lái)像下面這樣。 為了在屏幕截圖中顯示,間隔視圖顯示淺灰色背景:

如果您必須在故事板中執(zhí)行此操作,那么這不是一個(gè)問(wèn)題,但許多視圖都是動(dòng)態(tài)的。 由于相鄰的間隔視圖和約束,在運(yùn)行時(shí)添加新按鈕或隱藏或刪除現(xiàn)有按鈕并不是一項(xiàng)簡(jiǎn)單的任務(wù)。

要在堆棧視圖中隱藏視圖,請(qǐng)將包含視圖的hidden屬性設(shè)置為true,并使用堆棧視圖處理其余視圖。 這是當(dāng)用戶隱藏其下方的文本時(shí),您將如何修復(fù)WEATHER標(biāo)簽下的間距。 將weather部分標(biāo)簽添加到堆棧視圖后,您將在本教程中執(zhí)行此操作。

注意:您現(xiàn)在知道如何指定堆棧中子視圖之間的間距。 但是如果你想在特定的子視圖后有不同的間距呢? 從iOS 11開(kāi)始,您可以使用 setCustomSpacing:afterView來(lái)實(shí)現(xiàn)。


Converting the Sections

接下來(lái),您將轉(zhuǎn)換SpotInfoViewController中的所有其他部分以使用堆棧視圖。 這使您可以完成剩余的任務(wù)。 從rating部分開(kāi)始。

1. Converting the Rating Section

在您創(chuàng)建的堆棧視圖上方,選擇RATING標(biāo)簽和旁邊的星號(hào)標(biāo)簽。

然后,單擊Editor ? Embed in ? Stack View。

現(xiàn)在,選擇新創(chuàng)建的堆棧視圖,然后再次單擊Add New Constraints按鈕。 選中Constrain to margins并添加以下三個(gè)約束:

Top: 20, Leading: 0, Bottom: 20

現(xiàn)在轉(zhuǎn)到Attributes inspector并將間距設(shè)置為8

注意:您可能已經(jīng)注意到間距已經(jīng)設(shè)置為8。以前,間距自動(dòng)設(shè)置為24,Xcode已經(jīng)變得足夠聰明,可以推斷間距值以匹配嵌入視圖之前的間距值。 很酷,對(duì)嗎?

構(gòu)建并運(yùn)行以驗(yàn)證所有內(nèi)容與以前相同。

2. Un-embedding a Stack View

在你走得太遠(yuǎn)之前,最好在出現(xiàn)問(wèn)題時(shí)進(jìn)行一些急救培訓(xùn)。 例如,您可能會(huì)發(fā)現(xiàn)自己有一個(gè)額外的堆棧視圖,可能是因?yàn)閷?shí)驗(yàn),重構(gòu)或意外。

幸運(yùn)的是,從堆棧視圖中可以輕松地取消嵌入視圖。

首先,選擇要?jiǎng)h除的堆棧視圖。 單擊Embed In按鈕。 接下來(lái),在出現(xiàn)的上下文菜單中選擇Unembed

另一種方法是選擇堆棧視圖,然后從菜單中選擇Editor ? Unembed。

3. Creating a Vertical Stack View

現(xiàn)在,創(chuàng)建第一個(gè)垂直堆棧視圖。 選擇WHY VISIT標(biāo)簽和其下方的<whyVisitLabel>,然后選擇Embed in ? Stack View。

當(dāng)您在堆棧視圖中嵌入標(biāo)簽時(shí),Xcode會(huì)根據(jù)標(biāo)簽的位置推斷它應(yīng)該是一個(gè)垂直堆棧。

較低的標(biāo)簽之前有一個(gè)約束將其固定到右邊距,但是在堆棧視圖中嵌入標(biāo)簽會(huì)刪除該約束。 目前,堆棧視圖沒(méi)有約束,因此它采用其最大視圖的固有寬度。

選擇堆棧視圖后,單擊Add New Constraints按鈕。 將Top,LeadingTrailing約束設(shè)置為0,再次確保選中Constrain to margins。

然后,單擊底部約束右側(cè)的下拉菜單并選擇WEATHER (current distance = 20)

默認(rèn)情況下,Interface Builder會(huì)向您顯示最近鄰居的約束,對(duì)于底部約束,它是距離為15Hide按鈕。您需要約束到其下方的WEATHER標(biāo)簽。

最后,單擊Add 4 Constraints。 您現(xiàn)在應(yīng)該看到以下內(nèi)容:

現(xiàn)在您有一個(gè)擴(kuò)展的堆棧視圖,右邊緣固定到視圖的右邊緣。 但是,底部標(biāo)簽的寬度仍然相同。 您將通過(guò)更新堆棧視圖的alignment屬性來(lái)解決此問(wèn)題。

4. Alignment Property

alignment屬性確定堆棧視圖如何垂直于其軸放置其視圖。 對(duì)于垂直堆棧視圖,可能的值為Fill,Leading,CenterTrailing

水平堆棧視圖的可能alignment值略有不同:

水平堆棧視圖有.top而不是.leading,并且有.bottom而不是.trailing。 還有兩個(gè)屬性僅在水平方向有效,.firstBaseline.lastBaseline。

選擇每個(gè)值以查看它如何影響垂直堆棧視圖中的標(biāo)簽放置:

Fill:

Leading:

Center:

Trailing:

完成對(duì)每個(gè)值的測(cè)試后,將Alignment設(shè)置為Fill

構(gòu)建并運(yùn)行以驗(yàn)證一切看起來(lái)都很好并且沒(méi)有回歸。

指定Fill意味著您希望所有視圖都垂直于其軸填充堆棧視圖。 這會(huì)導(dǎo)致WHY VISIT標(biāo)簽也擴(kuò)展到右邊緣。

如果您只希望底部標(biāo)簽擴(kuò)展到邊緣怎么辦?

現(xiàn)在,它并不重要,因?yàn)閮蓚€(gè)標(biāo)簽在運(yùn)行時(shí)都有清晰的背景,但是當(dāng)你轉(zhuǎn)換weather部分時(shí)它會(huì)很重要。

您將學(xué)習(xí)如何使用額外的堆棧視圖來(lái)實(shí)現(xiàn)這一目標(biāo)。

5. Converting the What to See Section

轉(zhuǎn)換此部分與您已經(jīng)完成的操作類似。

  • 1) 首先,選擇WHAT TO SEE標(biāo)簽和下面的<whatToSeeLabel>
  • 2) 單擊Embed In按鈕,然后選擇Stack View。
  • 3) 單擊Pin按鈕。
  • 4) 選中Constrain to margins并添加以下四個(gè)約束:
Top: 20, Leading: 0, Trailing: 0, Bottom: 20
  • 5) 將堆棧視圖的Alignment設(shè)置為Fill。

您的故事板現(xiàn)在應(yīng)該如下所示:

這只剩下weather部分了。


Converting the Weather Section

由于Hide按鈕,weather部分比其他部分更復(fù)雜。

要轉(zhuǎn)換weather部分,您可以通過(guò)將WEATHER標(biāo)簽和Hide按鈕嵌入水平堆棧視圖來(lái)創(chuàng)建嵌套堆棧視圖。 然后,將該水平堆棧視圖和<weatherInfoLabel>嵌入到垂直堆棧視圖中。

它看起來(lái)像這樣:

請(qǐng)注意,WEATHER標(biāo)簽已擴(kuò)展為等于Hide按鈕的高度。 這將導(dǎo)致WEATHER標(biāo)簽的基線與其下方的文本之間產(chǎn)生額外的空間。

請(qǐng)記住,alignment指定垂直于堆棧視圖的位置。 因此,您可以將alignment設(shè)置為Bottom

但是,您不希望Hide按鈕的高度決定堆棧視圖的高度。

相反,您將從所有堆棧視圖中刪除Hide按鈕。

Hide按鈕仍將是頂級(jí)視圖的子視圖,您將從其中添加一個(gè)約束到WEATHER標(biāo)簽 - 它將位于堆棧視圖中。 沒(méi)錯(cuò),您將從堆棧視圖外部的按鈕添加約束到堆棧視圖中的標(biāo)簽!

選擇WEATHER標(biāo)簽和它下面的<weatherInfoLabel>,然后將它們堆疊在堆棧視圖中。

單擊Add New Constraints按鈕,選中Constrain to margins并添加以下四個(gè)約束:

Top: 20, Leading: 0, Trailing: 0, Bottom: 20

將堆棧視圖的Alignment設(shè)置為Fill

您需要在Hide按鈕的左邊緣和WEATHER標(biāo)簽的右邊緣之間存在約束,因此使用WEATHER標(biāo)簽填充堆棧視圖將不起作用。

但是,您確實(shí)希望底部的<weatherInfoLabel>填充堆棧視圖。

您可以通過(guò)將WEATHER標(biāo)簽僅嵌入垂直堆棧視圖來(lái)實(shí)現(xiàn)此目的。 請(qǐng)記住,垂直堆棧視圖的alignment可以設(shè)置為.leading,如果您將堆棧視圖拉伸超出其固有寬度,則其子視圖將保持與前端對(duì)齊。

使用document outline選擇WEATHER標(biāo)簽,或使用Control-Shift-click方法。 然后,將其嵌入新的堆棧視圖中。

Alignment設(shè)置為Leading,并確保Axis設(shè)置為Vertical

很好! 外部堆棧視圖拉伸內(nèi)部堆棧視圖以填充寬度,但內(nèi)部堆棧視圖允許標(biāo)簽保持其原始寬度!

建立并運(yùn)行,為什么Hide按鈕在文本中間懸空?

WEATHER標(biāo)簽嵌入堆棧視圖時(shí),它與Hide按鈕之間的任何約束都被刪除。

要添加新約束,請(qǐng)按住Control鍵并將Hide按鈕拖動(dòng)到WEATHER標(biāo)簽。

按住Shift鍵選擇多個(gè)選項(xiàng),然后選擇Horizontal SpacingFirst Baseline。 然后按Enter,或單擊彈出視圖外的任何位置:

構(gòu)建并運(yùn)行。 現(xiàn)在應(yīng)該正確定位Hide按鈕。 由于設(shè)置為隱藏的標(biāo)簽嵌入在堆棧視圖中,因此按Hide會(huì)隱藏標(biāo)簽并調(diào)整其下方的視圖 - 所有這些都無(wú)需手動(dòng)調(diào)整任何約束。

現(xiàn)在所有部分都在獨(dú)特的堆棧視圖中,您可以將它們嵌入到外部堆棧視圖中,這將使最后兩個(gè)任務(wù)變得微不足道。

1. Top-level Stack View

按住Command鍵并單擊以在outline view中選擇所有五個(gè)頂級(jí)堆棧視圖。

然后將它們?nèi)壳度氲揭粋€(gè)堆棧視圖中:

單擊Add New Constraints按鈕,選中Constrain to margins并向所有邊添加0的約束。 然后將Spacing設(shè)置為20并將Alignment設(shè)置為Fill。 您的故事板場(chǎng)景現(xiàn)在應(yīng)該如下所示:

構(gòu)建并運(yùn)行

當(dāng)WEATHER堆棧視圖嵌入外部堆棧視圖時(shí),看起來(lái)隱藏按鈕再次失去其約束。 沒(méi)問(wèn)題,只需按照以前的方式再次添加約束:

  • 按住Control鍵并從Hide按鈕拖動(dòng)到WEATHER標(biāo)簽。
  • 按住Shift鍵。
  • 選擇Horizontal SpacingBaseline。
  • Enter,或單擊彈出視圖外的任何位置。

建立并運(yùn)行。 Hide按鈕現(xiàn)在位于正確的位置。

2. Repositioning Views

現(xiàn)在所有部分都在頂級(jí)堆棧視圖中,您將修改WHAT TO SEE部分的位置,使其位于WEATHER部分之上。

從大綱視圖中選擇middle stack view,然后在第一個(gè)和第二個(gè)視圖之間拖動(dòng)它。

注意:將指針稍微保持在您之間拖動(dòng)的堆棧視圖的左側(cè),以便它仍然是外部堆棧視圖的子視圖。 小藍(lán)圈應(yīng)位于兩個(gè)堆棧視圖之間的左邊緣,而不是右邊緣:

3. Size Class Configurations

最后,將注意力轉(zhuǎn)移到列表中的剩余任務(wù)。 在橫向模式下,垂直空間非常重要,因此您希望將堆棧視圖的各個(gè)部分更緊湊的放在一起。 為此,當(dāng)垂直size classes是緊湊的時(shí),您將使用size classes將頂級(jí)堆棧視圖的間距設(shè)置為10而不是20。

選擇頂級(jí)堆棧視圖,然后在Attributes inspector中,單擊Spacing旁邊的+按鈕:

選擇Any WidthCompact Height,然后選擇Add Variation。

在新的hC字段中將Spacing設(shè)置為10

建立并運(yùn)行。 縱向模式下的間距應(yīng)保持不變。 旋轉(zhuǎn)模擬器并注意部分之間的間距已減小,按鈕現(xiàn)在從視圖底部有足夠的空間:

如果你沒(méi)有添加頂級(jí)堆棧視圖,你仍然可以使用size classes在分隔五個(gè)部分的四個(gè)約束中的每一個(gè)上將垂直間距設(shè)置為10,但是在一個(gè)地方設(shè)置它不是更好嗎?

你有更好的時(shí)間做一些有意義的事,比如動(dòng)畫!


Animation

目前,該應(yīng)用程序在隱藏和顯示天氣細(xì)節(jié)時(shí)非常跳躍。您將添加一些動(dòng)畫以平滑過(guò)渡。

堆棧視圖與UIView動(dòng)畫引擎兼容。這意味著動(dòng)畫排列的子視圖的外觀或消失的動(dòng)畫就像在動(dòng)畫塊中切換其isHidden屬性一樣簡(jiǎn)單。

更改已排列的子視圖的isHidden屬性會(huì)更新其父堆棧視圖的布局。如果該更新位于動(dòng)畫塊中,則如果您在動(dòng)畫塊中自己更改了布局,則它將是相同的。

是時(shí)候?qū)懸恍┐a了!打開(kāi)SpotInfoViewController.swift并查看updateWeatherInfoViews(hideWeatherInfo:animated :)

你會(huì)在方法的最后看到這些行:

weatherHideOrShowButton.setTitle(newButtonTitle, for: .normal)
weatherInfoLabel.hidden = shouldHideWeatherInfo

替換成下面的內(nèi)容

if animated {
  UIView.animate(withDuration: 0.3) {
    self.weatherHideOrShowButton.setTitle(newButtonTitle, for: .normal)
    self.weatherInfoLabel.isHidden = shouldHideWeatherInfo
  }
} else {
  weatherHideOrShowButton.setTitle(newButtonTitle, for: .normal)
  weatherInfoLabel.isHidden = shouldHideWeatherInfo
}

構(gòu)建并運(yùn)行,然后點(diǎn)擊HideShow按鈕。 動(dòng)畫版本不是更好嗎?

除了在堆棧視圖中包含的視圖上設(shè)置隱藏屬性的動(dòng)畫之外,還可以在堆棧視圖本身上設(shè)置動(dòng)畫屬性,例如alignment, distribution, spacing 甚至是 axi。

后記

本篇主要講述了UIStackView的使用,感興趣的給個(gè)贊或者關(guān)注~~~

?著作權(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)容