SwiftUI:动画过渡
SwiftUI: Animate Transitions
如何为不同视图之间的幻灯片切换设置动画?
在下面的示例代码中,我制作了一个选择器,用于选择要显示的视图,我的目标是实现类似于 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
转换完全一样,您还需要多做一步,事实上,现在 'old' 或 'previous' 视图在转换前消失。如果你想把它包含在堆栈中,你可以这样做:
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, 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)
}
}
}
如何为不同视图之间的幻灯片切换设置动画?
在下面的示例代码中,我制作了一个选择器,用于选择要显示的视图,我的目标是实现类似于 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
转换完全一样,您还需要多做一步,事实上,现在 'old' 或 'previous' 视图在转换前消失。如果你想把它包含在堆栈中,你可以这样做:
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, 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)
}
}
}