title: Conditionally updating a second property during animation in SwiftUI
body: <p>I have an animated <code>Arc</code> drawn in SwiftUI that represents data coming from two devices. When the arc animates to the left, the &quot;gauge&quot; is indicating that left device's data is higher than the right's and vice versa. The &quot;top&quot; is zero, which is 270 degrees when drawing an <code>Arc</code> shape. Because of this, I have a conditional set on a <code>clockwise</code> property so that the animation appears to go to the left or right of zero (270):</p>
  <pre><code>var clockwise: Bool {
      get { endAngle.degrees &gt; 270 ? false : true }
  }
  </code></pre>
  <p>When the property <code>endAngle</code> goes from less than 270 to greater than 270, or the reverse of this, the arc isn't drawn properly and appears as a circle because clockwise isn't set for portion of the animation passing through 270 to the new <code>endAngle</code>.</p>
  <p>Is there a way to delay the change in <code>clockwise</code> until the animation passes through 270 degrees?</p>
  <p>I've included the code for the view below with some comments. In order to animate <code>Angle</code>, it has to conform to <code>VectorArithmetic</code> which is the reason for the extension.</p>
  <pre><code>struct AverageGauge: View {
      
      @State var endAngle = Angle(degrees: 271.0)
      
      // Property I'd like to update during the animation
      var clockwise: Bool {
          get { endAngle.degrees &gt; 270 ? false : true }
      }
      
      var body: some View {
          VStack {
              Arc(startAngle: .degrees(270), endAngle: endAngle,
                  clockwise: clockwise)
                  .stroke(.red, style: StrokeStyle(lineWidth: 10, lineCap: .round, lineJoin: .round))
                  .frame(width: 100, height: 100)
                  // Tap gesture simulates changing data
                  .onTapGesture {
                      withAnimation(Animation.easeIn(duration: 2.0)) {
                       // endAngle animated here
                          endAngle = Angle(degrees: Double.random(in: 180...360))
                      }
              }
              Text(String(describing: endAngle.degrees))
              Text(&quot;\(String(clockwise))&quot;)
          }
      }
  }
  
  struct Arc: Shape {
      
      var startAngle: Angle
      var endAngle: Angle
      var clockwise: Bool
      
  //    var startAngleAnimatable: Angle {
  //        get { startAngle }
  //        set {startAngle = Angle(degrees: 270.0) }
  //    }
      
      // Required to animate endAngle
      var animatableData: Angle {
          get { endAngle }
          set { endAngle = newValue }
      }
      
  //    var clockwiseAnimatable: Bool {
  //        get { clockwise }
  //        set { clockwise = newValue }
  //    }
      
      func path(in rect: CGRect) -&gt; Path {
          var path = Path()
          path.addArc(center: CGPoint(x: rect.midX, y: rect.midY), radius: rect.width / 2, startAngle: startAngle, endAngle: endAngle, clockwise: clockwise)
  
          return path
      }
  }
  
  extension Angle: VectorArithmetic {
      
      public static var zero = Angle(degrees: 0.0)
      
      public static func + (lhs: Angle, rhs: Angle) -&gt; Angle {
          Angle(degrees: lhs.degrees + rhs.degrees)
      }
      
      public static func - (lhs: Angle, rhs: Angle) -&gt; Angle {
          Angle(degrees: lhs.degrees - rhs.degrees)
      }
      
      public static func += (lhs: inout Angle, rhs: Angle) {
          lhs = Angle(degrees: lhs.degrees + rhs.degrees)
      }
      
      public static func -= (lhs: inout Angle, rhs: Angle) {
          lhs = Angle(degrees: lhs.degrees - rhs.degrees)
      }
      
      public mutating func scale(by rhs: Double) {
          self.degrees = self.degrees * rhs
      }
      
      public var magnitudeSquared: Double {
          get { 0.0 }
      }
  }
  
  // Preview in case you want to paste it. 
  struct AverageGauge_Previews: PreviewProvider {
      static var previews: some View {
          AverageGauge()
      }
  }
  </code></pre>
  <p>Here's a gif of the animation. You can see that when the new value is on the same side as 270, it looks normal, however, when the animation traverses zero (270) it appears as a circle because <code>clockwise</code> is set incorrectly.</p>
  <p><a href="https://i.stack.imgur.com/YVk7v.gif" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/YVk7v.gif" alt="anglegif" /></a></p>