title: Activating an animation in SwiftUI automatically based on saved state
body: <p>I'm trying to write a view that displays 3 buttons, I cannot get the animation to start on load.</p>
  
  <p>When a button is tapped, I want it to animate until either:</p>
  
  <ol>
  <li>it is tapped a second time </li>
  <li>another of the 3 buttons is tapped</li>
  </ol>
  
  <p>I have got the code working using a @Environment object to store the running state. It toggles between the 3 buttons nicely: <a href="https://i.stack.imgur.com/H2ppZ.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/H2ppZ.png" alt="enter image description here"></a></p>
  
  <p>The code for this is here:</p>
  
  <pre><code>struct ContentView : View {
  
      @EnvironmentObject var model : ModelClockToggle
  
  
  
      var body: some View {
  
          VStack {
  
              ForEach(0...2) { timerButton in
  
               ActivityBreak(myId: timerButton)
                  .padding()
  
              }
          }
      }
  }
  
  
  import SwiftUI
  
  struct ActivityBreak : View {
      var myId: Int
      @EnvironmentObject var model : ModelClockToggle
  
      let anim1 = Animation.basic(duration: 1.0, curve: .easeInOut).repeatCount(Int.max)
      let noAni = Animation.basic(duration: 0.2, curve: .easeInOut).repeatCount(0)
  
      var body: some View {
  
              return Circle()
                  .foregroundColor(.red)
  
                  .scaleEffect(self.model.amIRunning(clock: self.myId) ? 1.0 : 0.6)
                  .animation( self.model.amIRunning(clock: self.myId) ? anim1 : noAni )
                  .tapAction {
  
                      self.model.toggle(clock: self.myId)
  
  
  
              }
  
      }
  }
  </code></pre>
  
  <p>For completeness, the model is:</p>
  
  <pre><code>import Foundation
  import SwiftUI
  import Combine
  
  
  class ModelClockToggle: BindableObject  {
  
      let didChange = PassthroughSubject&lt;ModelClockToggle, Never&gt;()
  
  
      private var clocksOn: [Bool]  = [false,false,false]
  
      init() {
          clocksOn = []
          clocksOn.append(UserDefaults.standard.bool(forKey: "toggle1"))
          clocksOn.append(UserDefaults.standard.bool(forKey: "toggle2"))
          clocksOn.append(UserDefaults.standard.bool(forKey: "toggle3"))
          debugPrint(clocksOn)
  
      }
  
  
  
      func toggle(clock: Int) {
          debugPrint(#function)
  
  
          if clocksOn[clock] {
              clocksOn[clock].toggle()
  
  
  
  
  
          } else {
              clocksOn  = [false,false,false]
              clocksOn[clock].toggle()
          }
          saveState()
          didChange.send(self)
      }
  
  
      func amIRunning(clock: Int) -&gt; Bool {
          debugPrint(clocksOn)
  
          return clocksOn[clock]
  
  
      }
  
      private func saveState() {
  
          UserDefaults.standard.set(clocksOn[0], forKey: "toggle1")
          UserDefaults.standard.set(clocksOn[1], forKey: "toggle2")
          UserDefaults.standard.set(clocksOn[2], forKey: "toggle3")
  
  
      }
  }
  </code></pre>
  
  <p>How do I make the repeating animation start at load time based on the @Environment object I have passed into the View? Right now SwiftUI only seems to consider state change once the view is loaded.</p>
  
  <p>I tried adding an .onAppear modifier, but that meant I had to use a different animator - which had very strange effects.</p>
  
  <p>help gratefully received.</p>