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

