在我的应用程序中,我有一个按钮,它的动画表明该应用程序当前正在执行与该按钮关联的功能。
一切正常,直到有必要在屏幕上隐藏/显示按钮(或包含它的视图)。 当按钮返回屏幕时,按钮动画停止工作。我明白为什么会发生这种情况(没有需要动画的状态变化),但我不明白它是如何容易解决的((
最终,无论按钮隐藏/显示多少次,我都希望按钮动画始终仅取决于动画显示的状态。
struct ContentView: View {
@State private var animationOn = false
@State private var showButton = true
let buttonAnimation = Animation.easeIn(duration: 1).repeatForever(autoreverses: false)
var body: some View {
VStack {
Toggle("Show button", isOn: $showButton)
.padding()
if showButton {
Image(systemName: "face.smiling")
.imageScale(.large)
.overlay(
Circle()
.stroke(Color.blue, lineWidth: animationOn ? 5 : 0)
.scaleEffect(animationOn ? 2 : 1)
.opacity(animationOn ? 0 : 1)
.animation(animationOn ? buttonAnimation : Animation.default)
)
.onTapGesture {
animationOn.toggle()
}
}
Text("animation is \(animationOn ? "on" : "off")")
.padding()
}
}
}
答案 0 :(得分:0)
我自己找到了解决方案)) 正如我已经写过的,关键是当按钮出现在屏幕上时,需要进行一些更改才能产生动画。 所需的操作在代码的注释中注明。
struct ContentView: View {
@State private var animationOn = false
@State private var showButton = true
let buttonAnimation = Animation.easeIn(duration: 1).repeatForever(autoreverses: false)
//1. declare properties for animation
@State private var lineWithForAnimation: CGFloat = 2
@State private var scaleEffectForAnimation: CGFloat = 2
@State private var opacityForAnimation: Double = 0
var body: some View {
VStack {
Toggle("Show button", isOn: $showButton)
.padding()
if showButton {
Image(systemName: "face.smiling")
.imageScale(.large)
.overlay(
Circle()
//2. use properties for animation
.stroke(Color.blue, lineWidth: lineWithForAnimation)
.scaleEffect(scaleEffectForAnimation)
.opacity(opacityForAnimation)
.animation(animationOn ? buttonAnimation : Animation.default)
)
.onTapGesture {
animationOn.toggle()
changeAnimatedProperties()
}
//3. change properties for animation onAppear
.onAppear{
changeAnimatedProperties()
}
//4. reset properties for animation onDisappear
.onDisappear{
resetAnimatedProperties()
}
}
Text("animation is \(animationOn ? "on" : "off")")
.padding()
}
}
func changeAnimatedProperties() {
lineWithForAnimation = animationOn ? 2 : 0
scaleEffectForAnimation = animationOn ? 2 : 1
opacityForAnimation = animationOn ? 0 : 1
}
func resetAnimatedProperties() {
lineWithForAnimation = 0
scaleEffectForAnimation = 1
opacityForAnimation = 1
}
}