在 SwiftUI 中呈现时,视图的不同元素的不同过渡
Different transitions for different elements of a view when it's presented in SwiftUI
所以当在 SwiftUI 中呈现视图时,我试图以不同的方式显示不同的元素(一个是从前缘滑入,另一个元素是幻灯片从屏幕底部向上)。我的基本视图结构如下:
struct ViewName: View {
@ObservedObject var appState: AppState //this is just a class that tracks the state of app variables, in my case it holds a variable called 'showView' that indicates whether or not to show the view.
var body: some View {
ZStack {
Color.white
.edgesIgnoringSafeArea(.all)
VStack {
Text("Test")
}.transition(AnyTransition.asymmetric(insertion: .move(edge: .leading), removal: .move(edge: .trailing)))
VStack {
Spacer()
HStack {
Text("Test2")
Spacer()
Text("Test3")
}
}.transition(AnyTransition.move(edge: .bottom))
}
}
}
在其他地方,我用类似的东西初始化了视图:
if appState.showView {
ViewName(appState: appState)
}
以及一个用于更改是否显示视图的按钮:
Button(action: {
withAnimation {
appState.showView.toggle()
}
}, label: {
Text("Click me")
})
虽然 Swift 似乎不知道如何处理这两个过渡,但它有点将它们默认为淡入不透明过渡。不知道如何解决这个问题。非常感谢任何帮助!
问题是你只有1个if appState.showView {
。
if appState.showView {
ViewName(appState: appState)
}
因此,SwiftUI 仅使用默认的淡入淡出过渡动画 整个 ViewName
(因为您没有指定)。
相反,您需要在每个要设置动画的单独元素上使用 if appState.showView {
。
class AppState: ObservableObject {
@Published var showView = false
}
struct ContentView: View {
@StateObject var appState = AppState()
var body: some View {
VStack {
Button(action: {
withAnimation {
appState.showView.toggle()
}
}, label: {
Text("Click me")
})
ViewName(appState: appState) /// just make this always showing
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.green)
}
}
struct ViewName: View {
@ObservedObject var appState: AppState
var body: some View {
ZStack {
if appState.showView { /// need this, so `ViewName` will be invisible when `appState.showView` is false
Color.white
.edgesIgnoringSafeArea(.all)
/// optional: add a transition here too
/// by default, it will fade
}
if appState.showView { /// need this!
VStack {
Text("Test")
}
.zIndex(1) /// needed for removal transition
.transition(AnyTransition.asymmetric(insertion: .move(edge: .leading), removal: .move(edge: .trailing)))
}
if appState.showView { /// need this!
VStack {
Spacer()
HStack {
Text("Test2")
Spacer()
Text("Test3")
}
}
.zIndex(2) /// needed for removal transition
.transition(AnyTransition.move(edge: .bottom))
}
}
}
}
所以当在 SwiftUI 中呈现视图时,我试图以不同的方式显示不同的元素(一个是从前缘滑入,另一个元素是幻灯片从屏幕底部向上)。我的基本视图结构如下:
struct ViewName: View {
@ObservedObject var appState: AppState //this is just a class that tracks the state of app variables, in my case it holds a variable called 'showView' that indicates whether or not to show the view.
var body: some View {
ZStack {
Color.white
.edgesIgnoringSafeArea(.all)
VStack {
Text("Test")
}.transition(AnyTransition.asymmetric(insertion: .move(edge: .leading), removal: .move(edge: .trailing)))
VStack {
Spacer()
HStack {
Text("Test2")
Spacer()
Text("Test3")
}
}.transition(AnyTransition.move(edge: .bottom))
}
}
}
在其他地方,我用类似的东西初始化了视图:
if appState.showView {
ViewName(appState: appState)
}
以及一个用于更改是否显示视图的按钮:
Button(action: {
withAnimation {
appState.showView.toggle()
}
}, label: {
Text("Click me")
})
虽然 Swift 似乎不知道如何处理这两个过渡,但它有点将它们默认为淡入不透明过渡。不知道如何解决这个问题。非常感谢任何帮助!
问题是你只有1个if appState.showView {
。
if appState.showView {
ViewName(appState: appState)
}
因此,SwiftUI 仅使用默认的淡入淡出过渡动画 整个 ViewName
(因为您没有指定)。
相反,您需要在每个要设置动画的单独元素上使用 if appState.showView {
。
class AppState: ObservableObject {
@Published var showView = false
}
struct ContentView: View {
@StateObject var appState = AppState()
var body: some View {
VStack {
Button(action: {
withAnimation {
appState.showView.toggle()
}
}, label: {
Text("Click me")
})
ViewName(appState: appState) /// just make this always showing
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.green)
}
}
struct ViewName: View {
@ObservedObject var appState: AppState
var body: some View {
ZStack {
if appState.showView { /// need this, so `ViewName` will be invisible when `appState.showView` is false
Color.white
.edgesIgnoringSafeArea(.all)
/// optional: add a transition here too
/// by default, it will fade
}
if appState.showView { /// need this!
VStack {
Text("Test")
}
.zIndex(1) /// needed for removal transition
.transition(AnyTransition.asymmetric(insertion: .move(edge: .leading), removal: .move(edge: .trailing)))
}
if appState.showView { /// need this!
VStack {
Spacer()
HStack {
Text("Test2")
Spacer()
Text("Test3")
}
}
.zIndex(2) /// needed for removal transition
.transition(AnyTransition.move(edge: .bottom))
}
}
}
}