问题描述
在下面的示例代码中,我制作了一个选择器来选择要显示的视图,我的目标是拥有一个看起来类似于 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)
}
}
}
解决方法
要获得您正在寻找的幻灯片动画,.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)
}
}
}
}
,
您是否真的需要黑色的 ZStack(在您的示例代码段中从未可见)?没有它,转换开箱即用(在模拟器中,而不是在 SwiftUI 预览中):
struct ContentView: View {
enum WhichScreen: String,yellow
}
@State private var whichScreen = WhichScreen.red
var body: some View {
VStack {
Picker("screen",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)
}
}
}