Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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."

like image 755
steventnorris Avatar asked Nov 14 '14 21:11

steventnorris


2 Answers

Swift 4 version:

if let curveValue = (userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber)?.uintValue {
    let curveAnimationOptions = UIViewAnimationOptions(rawValue: curveValue << 16)
    //...
}
like image 118
ergunkocak Avatar answered Oct 22 '22 23:10

ergunkocak


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)
  ...
}
like image 20
nickgraef Avatar answered Oct 22 '22 21:10

nickgraef