如何仅当触发标识为true时触发SwiftUI动画?
如何仅在trigger为true时触发SwiftUI keyframe动画,而非状态变化即执行?
这个需求完全可以实现。默认的keyframeAnimator会在trigger状态每次变更时重启动画,我们可以通过添加一个一次性触发的状态标记,让动画仅在trigger从false切换到true时执行。
解决方案代码示例
struct AnimationValues: Animatable { var scale: Double = 1.0 var animatableData: Double { get { scale } set { scale = newValue } } } struct ContentView: View { @State private var animationIsActive = false // 用于控制动画仅触发一次的标记 @State private var shouldTriggerAnimation = false var body: some View { Label("Test", systemImage: "magnifyingglass") .keyframeAnimator( initialValue: AnimationValues(), trigger: shouldTriggerAnimation ) { content, frame in content .scaleEffect(frame.scale) } keyframes: { _ in KeyframeTrack(\.scale) { LinearKeyframe(0.5, duration: 0.1) LinearKeyframe(1.5, duration: 0.1) LinearKeyframe(1.0, duration: 0.1) } } .onChange(of: animationIsActive) { oldValue, newValue in // 仅当状态从false变为true时,激活动画触发标记 if !oldValue && newValue { shouldTriggerAnimation = true } } .onAnimationCompleted(for: shouldTriggerAnimation) { // 动画完成后重置标记,确保下次状态切换能再次触发 shouldTriggerAnimation = false } } } // 扩展View,添加动画完成监听的便捷方法 extension View { func onAnimationCompleted<V: VectorArithmetic>(for value: V, completion: @escaping () -> Void) -> some View { self.modifier(AnimationCompletionModifier(observedValue: value, completion: completion)) } } struct AnimationCompletionModifier<V: VectorArithmetic>: AnimatableModifier { var observedValue: V var completion: () -> Void var animatableData: V { didSet { checkIfAnimationCompleted() } } init(observedValue: V, completion: @escaping () -> Void) { self.observedValue = observedValue self.completion = completion self.animatableData = observedValue } func body(content: Content) -> some View { content } private func checkIfAnimationCompleted() { if animatableData == observedValue { DispatchQueue.main.async { completion() } } } }
核心思路说明
- 新增触发标记:用
shouldTriggerAnimation作为动画的实际trigger,而非直接使用animationIsActive - 状态变化监听:通过
onChange监听animationIsActive的切换,仅当它从false变为true时,才将shouldTriggerAnimation设为true以触发动画 - 重置触发标记:动画完成后,通过自定义的
onAnimationCompleted方法重置shouldTriggerAnimation,确保下次animationIsActive再次变为true时,动画能重新触发
这样就能避免animationIsActive状态反复变化时重复触发动画,仅在需要的时机(从false到true的切换)执行一次动画。
内容的提问来源于stack exchange,提问作者GreatCornholio
相关产品推荐
相关产品推荐

