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
相关产品推荐
相关产品推荐

