Swift: NSNumber is not a subtype of UIViewAnimationCurve
Asked Answered
P

4

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?

Pepin answered 22/6, 2014 at 15:55 Comment(2)
UIView.setAnimationCurve(UIViewAnimationCurve.fromRaw((userInfo[UIKeyboardAnimationCurveUserInfoKey] as NSNumber).integerValue)!), syntactucally is okay, logically is not by all means.Johnston
Thanks! That also works without as NSNumber.Pepin
P
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))
Pepin answered 1/7, 2014 at 21:8 Comment(3)
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.Heraldry
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! :)Heraldry
The way I understand the docs (developer.apple.com/library/ios/documentation/uikit/reference/…) 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. ^^Heraldry
P
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)
Polyhydric answered 28/1, 2015 at 2:46 Comment(0)
R
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]?)
Ratchford answered 22/6, 2014 at 16:2 Comment(0)
I
0

My solution is

UIView.setAnimationCurve(UIViewAnimationCurve(rawValue: notification.userInfo![UIKeyboardAnimationCurveUserInfoKey]!.integerValue)!)
Icecold answered 5/11, 2015 at 12:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.