Skip to content

Instantly share code, notes, and snippets.

@timothycosta
Last active March 12, 2024 21:10
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save timothycosta/78e87544a90ce1670548407aac556ab3 to your computer and use it in GitHub Desktop.
Save timothycosta/78e87544a90ce1670548407aac556ab3 to your computer and use it in GitHub Desktop.
Create a SwiftUI Animation with the correct curve and duration from UIKit keyboard notifications
func animation(from notification: Notification) -> Animation? {
guard
let info = notification.userInfo,
let duration = info[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double,
let curveValue = info[UIResponder.keyboardAnimationCurveUserInfoKey] as? Int,
let uiKitCurve = UIView.AnimationCurve(rawValue: curveValue)
else {
return nil
}
let timing = UICubicTimingParameters(animationCurve: uiKitCurve)
return Animation.timingCurve(
Double(timing.controlPoint1.x),
Double(timing.controlPoint1.y),
Double(timing.controlPoint2.x),
Double(timing.controlPoint2.y),
duration: duration
)
}
@shywoody
Copy link

seem like UIKit keyboard animation ?

@remstos
Copy link

remstos commented Mar 6, 2023

This was such a great lead, but on iOS 16 and 15, (or at least 16.4 and 15.5 that I’m testing on) the control points are just linear (0 to 1), you can to take the spring timing parameters instead.

        let timing = UICubicTimingParameters(animationCurve: uiKitCurve)
        if let springParams = timing.springTimingParameters,
           let mass = springParams.mass, let stiffness = springParams.stiffness, let damping = springParams.damping {
            return Animation.interpolatingSpring(mass: mass, stiffness: stiffness, damping: damping)
        } else {
            return Animation.easeOut(duration: duration) // this is the closest fallback
        }

with this helper

private extension UISpringTimingParameters {
    var mass: Double? {
        value(forKey: "mass") as? Double
    }
    var stiffness: Double? {
        value(forKey: "stiffness") as? Double
    }
    var damping: Double? {
        value(forKey: "damping") as? Double
    }
}

Still hard to make SwiftUI be exactly in sync, but this is closest I could get.

@shywoody
Copy link

shywoody commented Mar 8, 2023

thx a lot, i'll try. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment