SwiftUI Animation使绑定条件视图闪烁



我对这个设置有一个问题:

ZStack {
ViewOne
if something ? ViewTwo : nil
}
.animation()

问题是,当动画开始时,ViewTwo闪烁打开和关闭。我认为这与视图重新渲染或其他东西有关?但我不太明白。我试过移动动画,分别在每个视图上使用它,在一个视图中组合它,但是当它基于条件时它总是闪烁。我想让两个视图一起动画。

这是一段可重复的代码片段。

struct ContentView: View {
@State var isAnimating: Bool

var body: some View {
ZStack {
VStack {
ForEach((1...5).reversed(), id: .self) {_ in
ZStack {
RoundedRectangle(cornerRadius: 5)
.foregroundColor(.blue)
.frame(width: 200, height: 50)
.rotationEffect(.degrees(isAnimating == true ? 5 : 0))
isAnimating
? ButtonImage()
: nil
}
.animation(
.easeInOut(duration: 0.3)
.repeatForever(autoreverses: true)
, value: isAnimating
)
}
Button(action: {
self.isAnimating.toggle()
}, label: {
Text("Animate")
})
}
}
.rotationEffect(.degrees(isAnimating == true ? 5 : 0))
}
}
struct ButtonImage: View {
private let buttonSize: CGSize = CGSize(width: 25, height: 25)

var body: some View {
Button(action: {
// to something
}) {
Image(systemName: "flame")
.resizable()
.renderingMode(.template)
.background(Color.red)
.foregroundColor(Color.yellow)
.frame(width: buttonSize.width, height: buttonSize.height)
}
.frame(width: buttonSize.width, height: buttonSize.height)
.offset(x: -buttonSize.width / 2, y: -buttonSize.height / 2)
}

有解决这个问题的办法吗?根据条件显示视图,同时在不闪烁的情况下使其动画化?

想到办法了!我不确定这是不是最好的方法,但它确实有效。

分别向两个视图添加动画,然后向第二个视图添加不透明度修改器。下面是我使用的代码:

struct ContentView: View {
@State var isAnimating: Bool

var body: some View {
ZStack {
VStack {
ForEach((1...5).reversed(), id: .self) {_ in
ZStack {
RoundedRectangle(cornerRadius: 5)
.foregroundColor(.blue)
.frame(width: 200, height: 50)
.rotationEffect(.degrees(isAnimating == true ? 5 : 0))
.animation(
.easeInOut(duration: 0.3)
.repeatForever(autoreverses: true)
, value: isAnimating
)
ButtonImage(isAnimating: $isAnimating)
.opacity(isAnimating ? 1 : 0)
}
}
Button(action: {
self.isAnimating.toggle()
}, label: {
Text("Animate")
})
}
}
.rotationEffect(.degrees(isAnimating == true ? 5 : 0))
}
}
struct ButtonImage: View {
private let buttonSize: CGSize = CGSize(width: 25, height: 25)
@Binding var isAnimating: Bool

var body: some View {
Button(action: {
// to something
}) {
Image(systemName: "flame")
.resizable()
.renderingMode(.template)
.background(Color.red)
.foregroundColor(Color.yellow)
.frame(width: buttonSize.width, height: buttonSize.height)
}
.frame(width: buttonSize.width, height: buttonSize.height)
.offset(x: -buttonSize.width / 2, y: -buttonSize.height / 2)
.rotationEffect(.degrees(isAnimating == true ? 5 : 0))
.animation(
.easeInOut(duration: 0.3)
.repeatForever(autoreverses: true)
, value: isAnimating
)
}
}

最新更新