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

