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

SwiftUI旋转动画减速失效反而加速问题求助

解决SwiftUI旋转动画调速时持续加速的问题

你的代码核心问题是每次调整速度时,旧的旋转动画没有被终止,新动画和旧动画叠加运行,导致视觉上速度越来越快。另外duration: 0.0的设置也不符合预期,会触发即时跳转而非停止动画。

下面是修正后的代码,解决了动画叠加和停止逻辑的问题:

import SwiftUI

struct ContentView: View {
    @State private var rotationAngle: Angle = .degrees(0)
    @State var imageSpeed: Double = 1.5
    @State private var isAnimating = false
    
    var body: some View {
        VStack {
            Image("j")
                .resizable()
                .frame(width: 100, height: 100)
                .rotationEffect(rotationAngle, anchor: .center)
                .onAppear {
                    startAnimation()
                }
                .onChange(of: imageSpeed) { _ in
                    restartAnimation()
                }
            
            HStack {
                Button(action: {
                    imageSpeed = 4
                }) {
                    Text("Slow")
                }
                
                Button(action: {
                    imageSpeed = 1
                }) {
                    Text("Fast")
                }
                
                Button(action: {
                    stopAnimation()
                }) {
                    Text("Stop")
                }
            }
            .padding(.top, 20)
        }
    }
    
    private func startAnimation() {
        guard !isAnimating else { return }
        isAnimating = true
        withAnimation(Animation.linear(duration: imageSpeed).repeatForever(autoreverses: false)) {
            rotationAngle = .degrees(360)
        }
    }
    
    private func restartAnimation() {
        // 先重置角度并终止旧动画
        withAnimation(.linear(duration: 0)) {
            rotationAngle = .degrees(0)
            isAnimating = false
        }
        // 延迟启动新动画,确保旧动画完全终止
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
            startAnimation()
        }
    }
    
    private func stopAnimation() {
        withAnimation(.linear(duration: 0)) {
            rotationAngle = .degrees(0)
            isAnimating = false
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

关键改动说明

  • 新增isAnimating状态变量,用于跟踪动画运行状态,避免重复启动动画
  • 拆分出三个独立方法管理动画逻辑,代码结构更清晰
  • restartAnimation中先通过0时长动画重置角度并标记动画停止,确保旧动画完全结束后再启动新动画,彻底避免动画叠加
  • Stop按钮直接调用stopAnimation,重置角度并终止所有动画,实现真正的停止效果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 08:35:16