利用 zIndex 調整頁面切換的動畫階層

SwiftUI 切換頁面有很多方法,除了使用 NavigationLink & sheet 幫我們切換,我們也可以利用 ZStack 容納頁面,然後用 if 控制頁面是否顯示,例如以下例子:

第一頁的畫面

struct FirstView: View {
var body: some View {
ZStack {
Color.pink
.edgesIgnoringSafeArea(.all)
Image(systemName: "1.circle")
.resizable()
.scaledToFit()
}
}
}

第二頁的畫面

struct SecondView: View {
var body: some View {
ZStack {
Color.yellow
.edgesIgnoringSafeArea(.all)
Image(systemName: "2.circle")
.resizable()
.scaledToFit()
}
}
}

用 ZStack 容納 FirstView & SecondView,然後用 if 控制 SecondView 的顯示。

struct ContentView: View {
@State private var showSecond = false

var body: some View {

ZStack {
FirstView()

if showSecond {
SecondView()
.transition(.move(edge: .bottom))
}

}
.onTapGesture {
withAnimation(.linear(duration: 5)) {
showSecond.toggle()
}
}

}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}

問題

以上做法沒什麼問題,然而當我們要從第二頁返回第一頁時,卻會看到奇怪的現象。從 SecondView 返回 FirstView 時,SecondView 即將被移除,它變成在底層,因此它會被 FirstView 蓋住,我們看不到它向下關閉消失的動畫。

解法

zIndex 控制元件的階層,元件預設的 zIndex 為 0,我們將 SecondView 的 zIndex 設為 1,讓它大於 FirstView,如此將保證 FirstView 會被 SecondView 壓在下面。

struct ContentView: View {
@State private var showSecond = false

var body: some View {

ZStack {

FirstView()

if showSecond {
SecondView()
.zIndex(1)
.transition(.move(edge: .bottom))
}

}
.onTapGesture {
withAnimation(.linear(duration: 5)) {
showSecond.toggle()
}
}

}
}

從第二頁返回第一頁時,順利看到第二頁向下關閉消失的動畫。

--

--

彼得潘的 iOS App Neverland
彼得潘的 Swift iOS App 開發問題解答集

彼得潘的iOS App程式設計入門,文組生的iOS App程式設計入門講師,彼得潘的 Swift 程式設計入門,App程式設計入門作者,http://apppeterpan.strikingly.com