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

SwiftUI点击按钮后Loading indicator加载指示器无旋转动画

SwiftUI 加载按钮旋转动画失效问题

场景与预期

实现点击触发加载状态的按钮,交互逻辑为:

  • 未加载时按钮显示Submit文案
  • 点击后将isLoading状态置为true,按钮内同步展示环形加载指示器 + Processing文案
    实际运行异常:点击按钮后,加载指示器未出现持续旋转的动画效果。

原实现代码

Button(action: {
    self.isLoading = true
}) {
    HStack {
        if isLoading {
            Circle()
                .trim(from: 0, to: 0.7)
                .stroke(Color.green, lineWidth: 5)
                .frame(width: 50, height: 50)
                .rotationEffect(Angle(degrees: isLoading ? 360 : 0))
                .animation(.default
                            .repeatForever(autoreverses: false), value: isLoading)
        }
            Text( isLoading ? "Processing" : "Submit")
                .fontWeight(.semibold)
                .font(.title)
        }
}
.frame(width: 250, height: 50)
.background(.white)

运行效果

运行效果演示

失效原因

动画绑定的触发值为isLoading,这个状态仅在点击时从false变更为true一次,后续没有持续的状态变化,repeatForever的循环动画缺少持续触发的条件,因此只会执行单次旋转后直接停止,不会循环转动。

修复方案

单独拆分控制旋转角度的状态变量,在加载状态触发时主动启动旋转动画,让循环效果可以持续执行。修复后代码如下:

struct LoadingButton: View {
    @State private var isLoading = false
    // 独立控制旋转角度的状态
    @State private var rotationDegrees = 0.0
    
    var body: some View {
        Button(action: {
            isLoading = true
            // 触发角度变更,启动无限循环动画
            withAnimation(.default.repeatForever(autoreverses: false)) {
                rotationDegrees = 360
            }
            // 此处可编写实际业务请求逻辑,请求结束后将isLoading置为false、rotationDegrees重置为0即可
        }) {
            HStack(spacing: 12) {
                if isLoading {
                    Circle()
                        .trim(from: 0, to: 0.7)
                        .stroke(Color.green, lineWidth: 5)
                        .frame(width: 30, height: 30)
                        .rotationEffect(Angle(degrees: rotationDegrees))
                }
                Text(isLoading ? "Processing" : "Submit")
                    .fontWeight(.semibold)
                    .font(.title)
            }
        }
        .frame(width: 250, height: 50)
        .background(.white)
    }
}

关键调整点

  • 将循环动画的绑定值从单次变更的isLoading替换为独立的旋转角度状态,避免动画触发源只生效一次
  • 点击进入加载状态时,主动触发旋转角度从0到360的变更,绑定在该状态上的无限循环动画会持续执行,实现指示器持续旋转的效果
  • 优化布局:原代码中环形指示器尺寸为50x50,和按钮高度一致会出现布局溢出,调整为30x30、给HStack加12的间距,视觉效果更协调
  • 业务逻辑处理完成后,记得将isLoading置为false、rotationDegrees重置为0,即可回到初始按钮状态

内容的提问来源于stack exchange,提问作者Sishu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 19:36:33