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

基于Apple Watch常亮场景阶段切换的动画未按预期运行

问题根因

你的代码存在两个核心问题导致动画无法恢复:

  1. 按scenePhase切换两套完全重复的ZStack结构,场景从非活跃切回活跃态时,活跃分支的ZStack不会再次触发onAppear(仅视图首次加载时会调用onAppear),animate状态不会更新,动画自然不会重启。
  2. 使用了无指定绑定值的animation修饰符,隐式动画触发时机不可控,也会导致动画恢复异常。

修正方案

直接通过状态控制动画启停,无需重复创建视图,同时监听scenePhase变化主动触发动画重启,修正后代码如下:

struct PulseView: View {
    
    @Environment(\.scenePhase) private var scenePhase
    @State var animate = false
    
    // 补充你原有逻辑中缺失的自定义属性/方法,可根据实际需求调整
    private func circlesColor() -> Color { .red }
    private let outerCircleSize: CGFloat = 100
    private let middleCircleSize: CGFloat = 60
    private let innerCircleSize: CGFloat = 20
    
    var body: some View {
        ZStack {
            ZStack {
                Circle().fill(circlesColor().opacity(0.25)).frame(width: outerCircleSize, height: outerCircleSize).scaleEffect(self.animate ? 1 : 0.01)
                Circle().fill(circlesColor().opacity(0.35)).frame(width: middleCircleSize, height: middleCircleSize).scaleEffect(self.animate ? 1 : 0.01)
                Circle().fill(circlesColor()).frame(width: innerCircleSize, height: innerCircleSize)
            }
            // 明确动画绑定的变化值,避免隐式动画异常
            .animation(animate ? Animation.easeInOut(duration: 1.5).repeatForever(autoreverses: true) : .default, value: animate)
            // 监听场景状态变化,主动控制动画启停
            .onChange(of: scenePhase) { newPhase in
                if newPhase == .active {
                    // 先重置再启动,避免状态更新被合并导致动画不触发
                    animate = false
                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
                        animate = true
                    }
                } else {
                    animate = false
                }
            }
            .onAppear {
                animate = true
            }
        }
    }
}

调整说明

  • 删掉重复的视图分支,无需根据scenePhase切换整个视图结构,避免视图重复创建带来的生命周期异常
  • 新增onChange监听scenePhase变化:场景回到活跃状态时,先重置animate为false再重新赋值为true,强制动画从头触发;非活跃状态下直接停止动画,符合常亮模式的适配要求
  • 给animation修饰符增加value: animate参数,明确动画仅响应animate值的变化,避免无效隐式动画干扰

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 06:06:04