6

How do I get the line below to compile?

UIView.setAnimationCurve(userInfo[UIKeyboardAnimationCurveUserInfoKey].integerValue)

Right now, it gives the compile error:

'NSNumber' is not a subtype of 'UIViewAnimationCurve'

Why does the compiler think userInfo[UIKeyboardAnimationCurveUserInfoKey].integerValue is an NSNumber when integerValue is declared as an Int?

class NSNumber : NSValue {
    // ...
    var integerValue: Int { get }`?
    // ...
}

I've had similar issues with other enum types. What is the general solution?

ma11hew28
  • 121,420
  • 116
  • 450
  • 651
  • 1
    `UIView.setAnimationCurve(UIViewAnimationCurve.fromRaw((userInfo[UIKeyboardAnimationCurveUserInfoKey] as NSNumber).integerValue)!)`, syntactucally is okay, logically is not by all means. – holex Jun 22 '14 at 16:20
  • Thanks! That also works without `as NSNumber`. – ma11hew28 Jul 01 '14 at 21:09

4 Answers4

13
UIView.setAnimationCurve(UIViewAnimationCurve.fromRaw(userInfo[UIKeyboardAnimationCurveUserInfoKey].integerValue)!)

Read more: Swift enumerations & fromRaw()

UPDATE

Based on this answer to How to use the default iOS7 UIAnimation curve, I use the new block-based animation method, + animateWithDuration:delay:options:animations:completion:, and get the UIViewAnimationOptions like so:

let options = UIViewAnimationOptions(UInt((userInfo[UIKeyboardAnimationCurveUserInfoKey] as NSNumber).integerValue << 16))
Community
  • 1
  • 1
ma11hew28
  • 121,420
  • 116
  • 450
  • 651
  • 1
    This solution leads to a `fatal error: unexpectedly found nil while unwrapping an Optional value` for me with XCode 6 beta 6. Can you please update your answer with the working solution? Thank you. – Jeehut Aug 21 '14 at 10:26
  • 1
    Using the block-based animation method is even better. But there's no need for left shifting here, just use `unsignedLongValue` instead of `integerValue << 16` and you'll be fine. This will make the line of code more readable. Thanks for updating! :) – Jeehut Aug 22 '14 at 13:24
  • 1
    The way I understand the docs (https://developer.apple.com/library/ios/documentation/uikit/reference/uiview_class/uiview/uiview.html#//apple_ref/doc/c_ref/UIViewAnimationOptions) any `NSUInteger` value should do the trick as this is the original type of a `UIViewAnimationOptions` value. Therefore I suggest to use `unsignedLongValue` which leads to a `UInt` type value in Swift (that will convert to `NSUInteger` and therefore has the same type as `UIViewAnimationOptions`). Hope this explains why. Now that you've asked I'm actually wondering why **your** solution is working in the first place. ^^ – Jeehut Aug 24 '14 at 18:29
2

I used the below code to construct an animation curve value from the user info dictionary:

let rawAnimationCurveValue = (userInfo[UIKeyboardAnimationCurveUserInfoKey] as NSNumber).unsignedIntegerValue
let keyboardAnimationCurve = UIViewAnimationCurve(rawValue: rawAnimationCurveValue)
Ryan
  • 5,416
  • 1
  • 39
  • 36
0

You have two problems:

  1. Optional numbers may be represented as NSNumbers and the result of any subscript operation should be an optional. In this case integerValue isn't an integer, it's an optional integer (the trailing '?')

  2. Enums aren't interchangeable with integers.

Try:

UIAnimationCurve(userInfo[UIAnimationCurveUserInfoKey]?)
David Berry
  • 40,941
  • 12
  • 84
  • 95
0

My solution is

UIView.setAnimationCurve(UIViewAnimationCurve(rawValue: notification.userInfo![UIKeyboardAnimationCurveUserInfoKey]!.integerValue)!)
Varun Naharia
  • 5,318
  • 10
  • 50
  • 84