You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何追踪SwiftUI按钮的动画状态并阻止其在动画中触发?

SwiftUI Button动画状态追踪与点击拦截方案

一、获取动画数据

系统默认Button的动画状态并未对外暴露,要获取动画数据(包括进度、状态),需要手动通过状态变量结合Animatable协议实现:

  1. 自定义可追踪动画进度的容器视图
    通过遵循Animatable协议,可实时获取动画的进度值:
struct AnimatingContainer<Content: View>: View, Animatable {
    var content: () -> Content
    var animationProgress: CGFloat
    
    // 绑定动画数据,系统会自动更新该值
    var animatableData: CGFloat {
        get { animationProgress }
        set { animationProgress = newValue }
    }
    
    init(animationProgress: CGFloat, @ViewBuilder content: @escaping () -> Content) {
        self.animationProgress = animationProgress
        self.content = content
    }
    
    var body: some View {
        content()
            .onChange(of: animationProgress) { newProgress in
                // 实时获取动画进度,按需处理(如存储、打印)
                print("当前动画进度:\(newProgress)")
            }
    }
}
  1. 在Button中集成并控制动画
    用状态变量管理动画的启动/结束状态,结合withAnimation触发动画并监听完成事件:
struct ContentView: View {
    @State private var isAnimating = false
    @State private var animationProgress: CGFloat = 0.0
    
    var body: some View {
        AnimatingContainer(animationProgress: animationProgress) {
            Button("触发动画") {
                guard !isAnimating else { return }
                isAnimating = true
                
                // 启动示例缩放动画,时长1秒
                withAnimation(.easeInOut(duration: 1.0).onCompletion {
                    isAnimating = false
                    animationProgress = 0.0
                }) {
                    animationProgress = 1.0
                }
            }
            .scaleEffect(animationProgress == 1.0 ? 0.8 : 1.0) // 绑定动画效果
        }
    }
}

二、阻止动画中触发点击操作

有两种实用实现方式:

  1. 直接在Button的action中判断状态
    在点击回调里先检查isAnimating,动画进行中则直接返回:
Button("触发动画") {
    guard !isAnimating else { return }
    // 后续动画逻辑
}
  1. 使用.disabled修饰符(推荐)
    给Button添加.disabled(isAnimating)修饰,既阻止点击,还会自动改变按钮视觉状态(如变灰),给用户明确反馈:
Button("触发动画") {
    // 动画逻辑
}
.scaleEffect(animationProgress == 1.0 ? 0.8 : 1.0)
.disabled(isAnimating)

内容的提问来源于stack exchange,提问作者Steven-Carrot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 19:24:10