學會這四個方法 讓你在 SwiftUI 中任意地平均佈局視圖!


本篇原文(標題: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()
}
swiftui-space-view-1

如你所見,Spacer 垂直地佔用了可用的空間。第一個 SpacerImage 推到螢幕頂部。如果想讓所有視圖等距分佈,就要在每個視圖之間添加一個 Spacer()

我們也可以在 Stacks 中添加間距,並對齊視圖。我們更可以搭配使用 Stack 間距 (spacing) 和 Spacer,靈活地排列視圖。

以下面的程式碼為例,我們利用一個 Spacer 來把 HStack 對齊螢幕左側。另外,我們還使用了 Stack 間距和對齊方式 (alignment),來排列 SwiftUI 的 Text

stack-and-alignment

現在,如果我們在兩個 Text 視圖之間放置另一個 Spacer(),效果會是怎樣呢?視圖會佔據整個螢幕,還是只會佔據 HStack 的可用高度?

答案是,由於我們尚未為 HStack 指定高度,因此視圖會佔據整個螢幕。為了確保 VStack 不會超出 HStack 的空間,我們可以設置一個固定的 frame 高度。

利用 Shapes

在上面的部分,我們了解到 SwiftUI 中的 TextsImages 如何佔據空間,但另一方面,Shapes 可以讓我們覆蓋更多的空間。

因此,我們可以把視圖放在 Shape 中,以填滿 Stack 的可用空間,並平均地佈局視圖。

看看以下例子:

swiftui-space-view-2

Shape 是平均填滿空間的好方法,你也可以利用 Shape 快速創建類似單元格 (cell) 的客製化視圖。

我們不會使用 overlay 視圖修飾符來放置子視圖,而是使用 ZStack

利用 Frame Modifier

通常,我們會創建寬度或高度相等的視圖。在這種情況下,我們可以使用 frame 修飾符,把 maxWidthmaxHeight 設置成 .infinity,以強制將寬度和高度設置為最大可用空間。

以下是 frame 佈局修飾符的使用範例:

swiftui-space-view-3

請注意,如果我們在 frame 前設置 background 修飾符,會導致 VStack 剩餘一些空間。因為 background 修飾符是應用於 Frame 的視圖,而不是整個 Stack。因此,正確排列視圖修飾符非常重要。

利用 Grids

雖然以上三種方法都足夠讓我們任意佈局視圖,但在視圖太多時,使用 SpacerFrame 修飾符可能會產生一些模組化程式碼 (boilerplate code)。

幸好,在這種情況下,我們可以利用 iOS 14 推出的 SwiftUI LazyVGridLazyHGrid

swiftui-space-view-4

在上面的程式碼中,我們創建了水平 Grid 物件,所以 SwiftUI Group 包裝的每個 Text 的寬度都會相同。

結論

在這篇文章中,我們說明了四種方法去管理視圖之間的空間。在組成視圖時,我們經常需要平均地佈局視圖。現在,我們已經學會了在甚麼情況下該應用這些技術!

本篇文章到此為止,謝謝你的閱讀。

本篇原文(標題:How To Evenly Space Views in SwiftUI)刊登於作者 Medium,由 Anupam Chugh 所著,並授權翻譯及轉載。

作者簡介:Anupam Chugh,深入探索 ML 及 AR 的 iOS Developer。喜愛撰寫關於想法、科技、與程式碼的文章。歡迎到我的 Blog 閱讀更多文章,或在 LinkedIn 上關注我。

譯者簡介:Kelly Chan-AppCoda 編輯小姐。


此文章為客座或轉載文章,由作者授權刊登,AppCoda編輯團隊編輯。有關文章詳情,請參考文首或文末的簡介。

blog comments powered by Disqus
Shares
Share This