SwiftUI 物件階層

設計App時,除了空件的位置之外,階層也是很重要的一環,它將決定A元件覆蓋B元件,還是被B元件所覆蓋.

在SwiftUI中主要有ZStack, Overlay 和 Background三種技術可以調整階層.

ZStack

ZStack和其他stack元件一樣,可在{ }中設定物件排列的順序,和HStack, VStack不一樣的是,ZStack是可以在三維空間中疊加的.

{ }中的元件,後面的元件會覆蓋於前一個元件.

以下例來說,會先加入一個Image後,Text會覆蓋在Image的上方.

ContentView.swift
1
2
3
4
5
6
7
8
struct ContentView: View {
var body: some View {
ZStack {
Image("testImage")
Text("Hello, world!")
}
}
}

alignment

ZStack 預設為將元件全部置中,但可以透過alignment參數控制對其的方式.

以alignment: .buttom為例,將圖片與文字對齊底部.

ContentView.swift
1
2
3
4
5
6
7
8
struct ContentView: View {
var body: some View {
ZStack(alignment: .bottom) {
Image("testImage")
Text("Curry")
}
}
}

padding & offset

我們也可以利用padding 和 offset來調整ZStack元件之間的間距.

ContentView.swift
1
2
3
4
5
6
7
8
struct ContentView: View {
var body: some View {
ZStack(alignment: .bottom) {
Image("testImage").padding(.bottom, 20)
Text("Curry").offset(x: -80, y: 0)
}
}
}

Overlay

如果不使用ZStack,我們也可以使用Overlay的方式達到此效果.

Overlay的作用是將物件疊加在自己身上.

ContentView.swift
1
2
3
4
5
struct ContentView: View {
var body: some View {
Image("testImage").overlay(Text("Curry"))
}
}

效果和第一張圖一樣,預設會將物件對齊於中間.

也可透過alignment的屬性來設置對齊方式.

ContentView.swift
1
2
3
4
5
struct ContentView: View {
var body: some View {
Image("testImage").overlay(Text("Curry"), alignment: .bottom)
}
}

結合padding & offset達到其第三圖的效果.

ContentView.swift
1
2
3
4
5
6
7
8
struct ContentView: View {
var body: some View {
Image("testImage")
.padding(.bottom, 20)
.overlay(Text("Curry").offset(x: -80, y: 0), alignment: .bottom)
}
}

Overlay可將多個物件疊加在自己身上,以下例來說,再多疊加一個 Image物件在上面.
此Image物件會在Text的上方,如果設計不好的話,會造成文字被圖片所擋住.

ContentView.swift
1
2
3
4
5
6
7
8
9
struct ContentView: View {
var body: some View {
Image("testImage")
.padding(.bottom, 20)
.overlay(Text("Curry").offset(x: -80, y: 0), alignment: .bottom)
.overlay(Image("basketball").resizable()
.frame(width: 72.0, height: 72.0).offset(x: -10, y: 90))
}
}

Background

Bakground和Overlay為相反疊加順序,Overlay是將物件疊加在自己身上,而Background是將自己疊加在物件身上.

ContentView.swift
1
2
3
4
5
6
struct ContentView: View {
var body: some View {
Image("testImage").resizable().frame(width: 150, height: 250, alignment: .center).offset(x: 20, y: 0)
.background( Image("curryBrand"))
}
}

Background也可以透過設定padding & Offset的方式調整內部物件的位置.

作者

Nick Lin

發表於

2021-03-25

更新於

2023-01-18

許可協議


評論