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

SwiftUI动画完成后随机修改状态的实现方案咨询

解决方案

要实现每次动画周期结束后切换随机旋转角度,无需复杂的自定义回调,直接利用iOS 15+提供的withAnimation(_:completion:)API即可完成,核心思路是手动循环触发动画,每次动画完成后生成新的随机角度并启动下一轮动画:

struct RotateView: View {
    @State var angle: CGFloat = 0
    
    var body: some View {
        Text("Rotate")
            .rotationEffect(Angle.degrees(angle))
            .onAppear {
                startRotationCycle()
            }
    }
    
    private func startRotationCycle() {
        // 生成新的随机旋转角度
        let targetAngle = CGFloat.random(in: -360...360)
        // 启动单次动画,完成后递归触发下一轮
        withAnimation(.easeInOut(duration: 2)) {
            angle = targetAngle
        } completion: {
            startRotationCycle()
        }
    }
}

struct RotateView_Previews: PreviewProvider {
    static var previews: some View {
        RotateView()
    }
}

说明

  • 移除了原代码中的.repeatForever(),改为单次动画+递归触发的模式,确保每次动画的目标角度都是新生成的随机值
  • withAnimation的completion闭包会在当前动画完全结束后执行,此时再调用startRotationCycle()就能无缝开启下一轮不同角度的旋转动画
  • 该方案无需自定义动画回调逻辑,完全依赖系统API实现,简洁且稳定

如果需要兼容iOS 15以下版本,可以用Timer配合withAnimation实现类似逻辑:

private func startRotationCycle() {
    let targetAngle = CGFloat.random(in: -360...360)
    withAnimation(.easeInOut(duration: 2)) {
        angle = targetAngle
    }
    // 延迟2秒(动画时长)后触发下一轮
    Timer.scheduledTimer(withTimeInterval: 2, repeats: false) { _ in
        startRotationCycle()
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 02:31:15