title: SwiftUI spring timing doesn't appear to match UIKit spring timing
body: <p>With identical parameters, the SwiftUI spring timing function doesn't appear to match the UIKit spring timing function (specifically, UIViewPropertyAnimator).</p>
  <p>In the video below, we have two labels, one in SwiftUI and one in UIKit, with positions being driven by spring functions with identical parameters, but the computed positions don't line up throughout the animation. What am I missing here?</p>
  <p><strong>Video</strong></p>
  <p><a href="https://i.stack.imgur.com/0UGzU.gif" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/0UGzU.gif" alt="enter image description here" /></a></p>
  <p><strong>Code</strong></p>
  <pre><code>import SwiftUI
  import UIKit
  
  class SwiftUIViewModel: ObservableObject {
      @Published var position: CGPoint = .zero
  }
  
  struct SwiftUIView: View {
      @ObservedObject var model: SwiftUIViewModel
      
      var body: some View {
          GeometryReader { geo in
              Text(&quot;Hello&quot;)
                  .font(.system(size: 100))
                  .foregroundColor(.blue)
                  .position(model.position)
                  .animation(.interpolatingSpring(mass: 1, stiffness: 39.47841760435743, damping: 12.566370614359172, initialVelocity: .zero))
          }
      }
  }
  
  class UIKitView: UIView {
      let referenceViewModel = SwiftUIViewModel()
      let referenceView: UIHostingController&lt;SwiftUIView&gt;
      
      let label = UILabel()
      
      var animator: UIViewPropertyAnimator?
      
      let tapGesture = UITapGestureRecognizer()
      
      var previousBounds: CGRect = .zero
  
      override func layoutSubviews() {
          guard bounds != previousBounds else {
              return
          }
          
          previousBounds = bounds
          
          label.sizeToFit()
          label.center = .init(x: bounds.width / 2, y: bounds.height / 2)
          
          referenceView.view.frame = bounds
      }
      
      init() {
          referenceView = UIHostingController(rootView: SwiftUIView(model: referenceViewModel))
          
          super.init(frame: .zero)
          
          tapGesture.addTarget(self, action: #selector(tapped))
          addGestureRecognizer(tapGesture)
          
          addSubview(referenceView.view)
          
          label.text = &quot;Hello&quot;
          label.textColor = .black
          label.adjustsFontSizeToFitWidth = true
          label.font = .systemFont(ofSize: 100.0)
          label.layer.opacity = 1.0
          addSubview(label)
      }
      
      @objc func tapped(_ event: UIEvent) {
          let location = tapGesture.location(in: self)
          
          // Forward to reference view.
          referenceViewModel.position = location
          
          let timing = UISpringTimingParameters(mass: 1, stiffness: 39.47841760435743, damping: 12.566370614359172, initialVelocity: .zero)
          animator = UIViewPropertyAnimator(duration: 0.0, timingParameters: timing)
          animator.addAnimations { [weak self] in
              self?.label.center = location
          }
          
          animator.startAnimation()
      }
      
      required init?(coder: NSCoder) {
          fatalError(&quot;init(coder:) has not been implemented&quot;)
      }
  }
  </code></pre>