我正在尝试创建一个非常简单的过渡动画,该动画可以通过点击按钮在屏幕中央显示/隐藏消息:
struct ContentView: View {
@State private var showMessage = false
var body: some View {
ZStack {
Color.yellow
VStack {
Spacer()
Button(action: {
withAnimation(.easeOut(duration: 3)) {
self.showMessage.toggle()
}
}) {
Text("SHOW MESSAGE")
}
}
if showMessage {
Text("HELLO WORLD!")
.transition(.opacity)
}
}
}
}
根据.transition(.opacity)
动画的文档
插入时从透明过渡到不透明,以及从不透明过渡 清除后变为透明。
当showMessage
状态属性为true时,消息应淡入,而当其为false时,消息应淡出。就我而言,这是不正确的。该消息以淡入淡出的动画显示,但它完全没有动画隐藏。有什么想法吗?
编辑:在下面的gif中,从模拟器中查看结果。
答案 0 :(得分:31)
我的发现是不透明过渡并不总是有效。 (不过,将幻灯片与.animation结合使用是可以的。)
.transition(.opacity) //does not always work
如果我将其编写为自定义动画,它将起作用:
.transition(AnyTransition.opacity.animation(.easeInOut(duration: 0.2)))
.zIndex(1)
答案 1 :(得分:6)
问题是,当视图在ZStack中来来去去时,其“ zIndex”不会保持不变。发生的情况是,当“ showMessage”从true变为false时,带有“ Hello World”文本的VStack被放置在堆栈的底部,黄色立即被绘制在其顶部。它实际上正在逐渐消失,但是它在黄色后面显示,所以您看不到它。
要解决此问题,您需要为堆栈中的每个视图明确指定“ zIndex”,以使它们始终保持不变-像这样:
struct ContentView: View {
@State private var showMessage = false
var body: some View {
ZStack {
Color.yellow.zIndex(0)
VStack {
Spacer()
Button(action: {
withAnimation(.easeOut(duration: 3)) {
self.showMessage.toggle()
}
}) {
Text("SHOW MESSAGE")
}
}.zIndex(1)
if showMessage {
Text("HELLO WORLD!")
.transition(.opacity)
.zIndex(2)
}
}
}
}
答案 2 :(得分:2)
我更喜欢Scott Gribben的答案(请参阅下文),但是由于我无法删除此答案(由于绿色的勾号),因此我将保留原始答案。我会争论,但我确实认为它是一个错误。有人希望zIndex由代码中显示的订单视图隐式分配。
要解决此问题,您可以将if语句嵌入VStack中。
struct ContentView: View {
@State private var showMessage = false
var body: some View {
ZStack {
Color.yellow
VStack {
Spacer()
Button(action: {
withAnimation(.easeOut(duration: 3)) {
self.showMessage.toggle()
}
}) {
Text("SHOW MESSAGE")
}
}
VStack {
if showMessage {
Text("HELLO WORLD!")
.transition(.opacity)
}
}
}
}
}
答案 3 :(得分:1)
我认为这是画布的问题。我今天早上正在玩转场游戏,虽然它们不能在画布上工作,但它们确实可以在模拟器中工作。试试看。我已经将该错误报告给了Apple。
答案 4 :(得分:0)
zIndex
可能会导致动画在中断时被破坏。在VStack
,HStack
中包装您要应用转换的视图,否则其他容器都将是有意义的。
答案 5 :(得分:0)
我在swiftUI_preview中发现了一个动画错误。当您在代码中使用过渡动画并希望在SwiftUI_preview中看到它时,它将不显示动画,或者仅在某些视图随动画消失时显示。为了解决这个问题,您只需要在VStack的预览中添加视图。像这样:
struct test_UI: View {
@State var isShowSideBar = false
var body: some View {
ZStack {
Button("ShowMenu") {
withAnimation {
isShowSideBar.toggle()
}
}
if isShowSideBar {
SideBarView()
.transition(.slide)
}
}
}
}
struct SomeView_Previews: PreviewProvider {
static var previews: some View {
VStack {
SomeView()
}
}
}
此后,所有动画都将发生。