本篇原文(標題:How To Evenly Space Views in SwiftUI )刊登於作者 Medium,由 Anupam Chugh 所著,並授權翻譯及轉載。
我早前花了幾個月開發 UIKit 專案,最近終於回到 SwiftUI。奇怪的是,我竟然花了一些時間來編寫最基本的原型:如何在我的圖像過濾 SwiftUI App 中,平均地佈局兩個圖像呢?
我試過在 HStack
中的兩個 Images
上,設置 resizable()
和 AspectRatio()
修飾符,但是沒有成功。實際上,由於實際的圖像資源太大,因此其中一個圖像佔據了整個螢幕。當然,我們還是可以寫死 (hardcode) 寬度和高度,但這不是對所有螢幕尺寸和方向都有效。
我暫停了 SwiftUI 開發一段時間,現在很高興能跟大家分享不同的技巧,來在 SwiftUI 中佈局視圖。讓我們開始吧!
利用 Spacers、Stack Spacing 和 Alignment
顧名思義,Spacers
會佔用可用的空間,而它們填充空間的方式,就視乎我們把 Spacers
包裝在 HStack
還是 VStack
中。
看看以下例子:
VStack {
Image(systemName: "shield.fill")
Spacer()
}
如你所見,Spacer
垂直地佔用了可用的空間。第一個 Spacer
將 Image
推到螢幕頂部。如果想讓所有視圖等距分佈,就要在每個視圖之間添加一個 Spacer()
。
我們也可以在 Stacks
中添加間距,並對齊視圖。我們更可以搭配使用 Stack
間距 (spacing) 和 Spacer
,靈活地排列視圖。
以下面的程式碼為例,我們利用一個 Spacer
來把 HStack
對齊螢幕左側。另外,我們還使用了 Stack
間距和對齊方式 (alignment),來排列 SwiftUI 的 Text
:
現在,如果我們在兩個 Text
視圖之間放置另一個 Spacer()
,效果會是怎樣呢?視圖會佔據整個螢幕,還是只會佔據 HStack
的可用高度?
答案是,由於我們尚未為 HStack
指定高度,因此視圖會佔據整個螢幕。為了確保 VStack
不會超出 HStack
的空間,我們可以設置一個固定的 frame
高度。
利用 Shapes
在上面的部分,我們了解到 SwiftUI 中的 Texts
和 Images
如何佔據空間,但另一方面,Shapes
可以讓我們覆蓋更多的空間。
因此,我們可以把視圖放在 Shape
中,以填滿 Stack 的可用空間,並平均地佈局視圖。
看看以下例子:
Shape 是平均填滿空間的好方法,你也可以利用 Shape 快速創建類似單元格 (cell) 的客製化視圖。
我們不會使用 overlay
視圖修飾符來放置子視圖,而是使用 ZStack
。
利用 Frame Modifier
通常,我們會創建寬度或高度相等的視圖。在這種情況下,我們可以使用
frame
修飾符,把 maxWidth
或 maxHeight
設置成 .infinity
,以強制將寬度和高度設置為最大可用空間。
以下是 frame
佈局修飾符的使用範例:
請注意,如果我們在 frame
前設置 background
修飾符,會導致 VStack
剩餘一些空間。因為 background
修飾符是應用於 Frame 的視圖,而不是整個 Stack。因此,正確排列視圖修飾符非常重要。
利用 Grids
雖然以上三種方法都足夠讓我們任意佈局視圖,但在視圖太多時,使用 Spacer
或 Frame
修飾符可能會產生一些模組化程式碼 (boilerplate code)。
幸好,在這種情況下,我們可以利用 iOS 14 推出的 SwiftUI LazyVGrid
和 LazyHGrid
。
在上面的程式碼中,我們創建了水平 Grid 物件,所以 SwiftUI Group
包裝的每個 Text
的寬度都會相同。
結論
在這篇文章中,我們說明了四種方法去管理視圖之間的空間。在組成視圖時,我們經常需要平均地佈局視圖。現在,我們已經學會了在甚麼情況下該應用這些技術!
本篇文章到此為止,謝謝你的閱讀。