設計App時,除了空件的位置之外,階層也是很重要的一環,它將決定A元件覆蓋B元件,還是被B元件所覆蓋.
在SwiftUI中主要有ZStack, Overlay 和 Background三種技術可以調整階層.
ZStack
ZStack和其他stack元件一樣,可在{ }中設定物件排列的順序,和HStack, VStack不一樣的是,ZStack是可以在三維空間中疊加的.
{ }中的元件,後面的元件會覆蓋於前一個元件.
以下例來說,會先加入一個Image後,Text會覆蓋在Image的上方.
ContentView.swift1 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.swift1 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.swift1 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.swift1 2 3 4 5
| struct ContentView: View { var body: some View { Image("testImage").overlay(Text("Curry")) } }
|
效果和第一張圖一樣,預設會將物件對齊於中間.
也可透過alignment的屬性來設置對齊方式.
ContentView.swift1 2 3 4 5
| struct ContentView: View { var body: some View { Image("testImage").overlay(Text("Curry"), alignment: .bottom) } }
|
結合padding & offset達到其第三圖的效果.
ContentView.swift1 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.swift1 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.swift1 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的方式調整內部物件的位置.