Toggling Animation based on Apple Watch's Always On Scenen Phase not working as expected?

304 Views Asked by At

I may be doing something wrong, but following Apple's Docs for how to pause animation to support Always On in WatchOS 8, with the code below my animation will pause correctly when the the scene phase is inactive, but when it becomes active again the animation does not resume?

struct PulseView: View {
    
    @Environment(\.scenePhase) private var scenePhase
    
    @State var animate = false
    
    var body: some View {
        if scenePhase == .active {
                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)
                    }
                    .onAppear { self.animate = true }
                    .animation(animate ? Animation.easeInOut(duration: 1.5).repeatForever(autoreverses: true) : .default)
                   
          } else {
                  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)
                      }
                      //.onAppear { self.animate = true }
                      //.animation(animate ? Animation.easeInOut(duration: 1.5).repeatForever(autoreverses: true) : .default)
          }
     
    }
1

There are 1 best solutions below

0
GarySabo On

I should have realized why it wasn't working, but adding a toggle to animate using an OnChangeOf modifier solved this issue.

 struct PulseView: View {
        
        @Environment(\.scenePhase) private var scenePhase
        
        @State var animate = false
        
        var body: some View {
            if scenePhase == .active {
                    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)
                        }
                        .onAppear { self.animate = true }
                        //HERE BELOW
                        .onChange(of: scenePhase, perform: { newValue in
                          if newValue == .active {
                             self.animate = true
                          } else {
                             self.animate = false
                          }
                         })
                        .animation(animate ? Animation.easeInOut(duration: 1.5).repeatForever(autoreverses: true) : .default)
                       
              } else {
                      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)
                          }
                          //.onAppear { self.animate = true }
                          //.animation(animate ? Animation.easeInOut(duration: 1.5).repeatForever(autoreverses: true) : .default)
              }
         
        }