Search code examples
iosswiftkeyboarduiviewanimationuiviewanimation-curve

Keyboard Animation Curve as Int


I am trying to get the UIAnimationCurve of the keyboard, if it exists. The code I am using is below:

if let kbCurve = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? Int{
                animateCurve = UIViewAnimationCurve.
            }

However, animateCurve, being a UIViewAnimationCurve, cannot be converted from an Int. How do I get the curve this way?

If I treat them as numbers, not UIViewAnimationCurve enums, the below errors when attempting to animate:

//Animated done button with keyboard
        origDoneFrame = btnDone.frame
        btnDone.hidden = false
        UIView.animateWithDuration(
            animateDuration,
            delay: Numbers.ANIMATE_DELAY,
            options: nil,
            animations: {
                UIView.setAnimationCurve(animateCurve)
                self.btnDone.frame = CGRectMake(self.btnDone.frame.origin.x + kbHeight, self.btnDone.frame.origin.y, self.btnDone.frame.size.width, self.btnDone.frame.size.height)
                return Void()
            },
            completion: {finished in
                return Void()
            }
        )

Is there a way to set the curve using an int?

Attempted int curve with:

UIView.animateWithDuration(
            animateDuration,
            delay: Numbers.ANIMATE_DELAY,
            options: UIViewAnimationOptions(animateCurve << 16),
            animations: {
                self.btnDone.frame = CGRectMake(self.btnDone.frame.origin.x + kbHeight, self.btnDone.frame.origin.y, self.btnDone.frame.size.width, self.btnDone.frame.size.height)
                return Void()
            },
            completion: {finished in
                return Void()
            }
        )

But compile error occurs due to UIViewAnimationOptions not being correct type. If I run the assignment of UIViewAnimationOptions on it's own, I get the compiler error "Could not find an overload for 'init' that accepts the supplied arguments."


Solution

  • You can get an enum value from the raw Int value with

    animateCurve = UIViewAnimationCurve(rawValue: kbCurve)
    

    However, the standard keyboard uses an animation curve value of 7, which might not match up with an enum value, so animateCurve would be nil. If this is the case, just define animateCurve as an Int and use the raw values in your code rather than the enum values.

    Additionally, a quick Google search turned up this wrapper, which might be useful to you: https://gist.github.com/kristopherjohnson/13d5f18b0d56b0ea9242

    Update to answer edited question:

    You can use an integer animation curve value in the animation options by converting it to a UIViewAnimationOptions value:

    UIViewAnimationOptions(kbCurve << 16)  // where kbCurve: UInt
    

    Update for Swift 1.2 (XCode 6.3):

    The release notes for Swift 1.2 indicate that NS_ENUM types with undocumented values can now be converted from their raw integer values without being reset to nil. So the following code will now work:

    let animateCurve = UIViewAnimationCurve(rawValue: userInfo[UIKeyboardAnimationCurveUserInfoKey].integerValue)!
    

    Update for Swift 2.2 (XCode 7.3):

    if let animationCurveInt = (userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber)?.unsignedIntegerValue {
      let animationCurve = UIViewAnimationOptions(rawValue: animationCurveInt<<16)
      ...
    }