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

SwiftUI加载指示器动画出现异常位移问题求助

解决SwiftUI环形加载指示器旋转时的位移问题

问题原因

你遇到的位移问题,本质是旧版无value参数的.animation修饰符会把动画应用到视图的所有属性变化上,包括布局计算时的微小调整。环形视图旋转时,SwiftUI可能因stroke宽度、trim裁剪范围等因素,在动画过程中重新计算布局边界,导致轻微位移,动画循环时就会反复出现复位再位移的现象。

解决方案

推荐两种修复方式,优先选择第一种:

方案1:使用withAnimation精确控制动画

这种方式只针对旋转角度的变化应用动画,避免影响布局:

struct LoadingIndicator: View {
    @State private var rotationAngle = 0.0
    
    var body: some View {
        ZStack {
            // 背景环形
            Circle()
                .stroke(Color(.systemGray5), lineWidth: 40)
                .frame(width: 250, height: 250)
            
            // 旋转的进度环形
            Circle()
                .trim(from: 0, to: 0.2)
                .stroke(Color.gray, lineWidth: 40)
                .frame(width: 250, height: 250)
                .rotationEffect(Angle(degrees: rotationAngle))
        }
        .onAppear {
            withAnimation(Animation.linear(duration: 1).repeatForever(autoreverses: false)) {
                rotationAngle = 360
            }
        }
    }
}

方案2:使用带value参数的.animation修饰符

如果坚持用状态变量触发动画,给.animation加上value参数,明确只在旋转角度变化时触发动画:

struct LoadingIndicator: View {
    @State private var isCircleRotating = false
    
    var body: some View {
        ZStack {
            Circle()
                .stroke(Color(.systemGray5), lineWidth: 40)
                .frame(width: 250, height: 250)
            
            Circle()
                .trim(from: 0, to: 0.2)
                .stroke(Color.gray, lineWidth: 40)
                .frame(width: 250, height: 250)
                .rotationEffect(Angle(degrees: isCircleRotating ? 360 : 0))
                // 仅当isCircleRotating变化时应用动画
                .animation(Animation.linear(duration: 1).repeatForever(autoreverses: false), value: isCircleRotating)
        }
        .onAppear {
            isCircleRotating = true
        }
    }
}

额外注意点

  • 无需给背景环形加.animation(nil),上述方案已经限制了动画范围,不会影响背景视图
  • 如果仍有微小偏移,可以给旋转的环形视图显式添加.anchorPoint(CGPoint(x: 0.5, y: 0.5)),强制锚点为中心(默认就是中心,但显式设置能避免特殊场景下的计算偏差)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 14:45:32