SwiftUI:动画转换



如何在不同视图之间设置幻灯片转换的动画?

在下面的示例代码中,我制作了一个Picker,用于选择要显示的视图,我的目标是生成一个类似于NavigationLink转换的转换。目前它根本没有动画。如果我将.animation(.easeInOut(duration: 2))修改器添加到ZStack,它会为淡入淡出动画设置2秒的动画,但我不明白为什么。

struct ContentView: View {
enum WhichScreen: String, CaseIterable {
case red, blue, green, yellow
}
@State private var whichScreen = WhichScreen.red
var body: some View {
VStack {
Picker("screen", selection: $whichScreen.animation()) {
ForEach(WhichScreen.allCases, id: .self) { value in
Text(value.rawValue).tag(value)
}
}
.pickerStyle(SegmentedPickerStyle())
ZStack {
Color.black
switch whichScreen {
case .red:
Color.red
case .blue:
Color.blue
case .green:
Color.green
case .yellow:
Color.yellow
}
}
.transition(.slide)
}
}
}

你真的需要黑色的ZStack吗(在你的示例片段中永远看不到(?如果没有它,转换就可以开箱即用(在模拟器中,而不是在SwiftUI预览中(:

struct ContentView: View {
enum WhichScreen: String, CaseIterable {
case red, blue, green, yellow
}
@State private var whichScreen = WhichScreen.red
var body: some View {
VStack {
Picker("screen", selection: $whichScreen.animation()) {
ForEach(WhichScreen.allCases, id: .self) { value in
Text(value.rawValue).tag(value)
}
}
.pickerStyle(SegmentedPickerStyle())
Group {
switch whichScreen {
case .red:
Color.red
case .blue:
Color.blue
case .green:
Color.green
case .yellow:
Color.yellow
}
}
.transition(.slide)
}
}
}

要获得您想要的幻灯片动画,.transition需要仅应用于您想要滑动的部分(例如,本例中的非黑色(:

ZStack {
Color.black
Group {
switch whichScreen {
case .red:
Color.red
case .blue:
Color.blue
case .green:
Color.green
case .yellow:
Color.yellow
}
}.transition(.slide)
}

如果您希望它与NavigationLink转换完全一样,您还有一步要做,即现在,"旧"或"以前"视图在转换之前消失。如果你想把它包括在堆栈中,你可以这样做:

struct ContentView: View {

enum WhichScreen: String, CaseIterable {
case red, blue, green, yellow
}

@State private var whichScreen = WhichScreen.red
@State private var previousScreen : WhichScreen? = .none

var body: some View {
VStack {
Picker("screen", selection: $whichScreen.animation()) {
ForEach(WhichScreen.allCases, id: .self) { value in
Text(value.rawValue).tag(value)
}
}
.pickerStyle(SegmentedPickerStyle())
.onChange(of: whichScreen) { [whichScreen] _ in
previousScreen = whichScreen
}
ZStack {
Color.black
if let previousScreen = previousScreen {
switch(previousScreen) {
case .red:
Color.red
case .blue:
Color.blue
case .green:
Color.green
case .yellow:
Color.yellow
}

}
Group {
switch whichScreen {
case .red:
Color.red
case .blue:
Color.blue
case .green:
Color.green
case .yellow:
Color.yellow
}
}.transition(.slide)
}
}
}
}

最新更新