iOS:如何将UIViewAnimationCurve转换为UIViewAnimationOptions?
UIKeyboardAnimationCurveUserInfoKey
有一个UIViewAnimationCurve
值。 如何将其转换为相应的UIViewAnimationOptions
值,以便与+[UIView animateWithDuration:delay:options:animations:completion:]
的options
参数一起使用。
// UIView.h typedef enum { UIViewAnimationCurveEaseInOut, // slow at beginning and end UIViewAnimationCurveEaseIn, // slow at beginning UIViewAnimationCurveEaseOut, // slow at end UIViewAnimationCurveLinear } UIViewAnimationCurve; // ... enum { // ... UIViewAnimationOptionCurveEaseInOut = 0 << 16, // default UIViewAnimationOptionCurveEaseIn = 1 << 16, UIViewAnimationOptionCurveEaseOut = 2 << 16, UIViewAnimationOptionCurveLinear = 3 << 16, // ... }; typedef NSUInteger UIViewAnimationOptions;
显然,我可以使用switch
语句创build一个简单的类别方法,如下所示:
// UIView+AnimationOptionsWithCurve.h @interface UIView (AnimationOptionsWithCurve) @end // UIView+AnimationOptionsWithCurve.m @implementation UIView (AnimationOptionsWithCurve) + (UIViewAnimationOptions)animationOptionsWithCurve:(UIViewAnimationCurve)curve { switch (curve) { case UIViewAnimationCurveEaseInOut: return UIViewAnimationOptionCurveEaseInOut; case UIViewAnimationCurveEaseIn: return UIViewAnimationOptionCurveEaseIn; case UIViewAnimationCurveEaseOut: return UIViewAnimationOptionCurveEaseOut; case UIViewAnimationCurveLinear: return UIViewAnimationOptionCurveLinear; } } @end
但是,有没有更简单/更好的方法?
可以说,你可以把你的第一个解决scheme,并使其内联function,以节省自己的堆栈推。 这是一个非常严格的条件(常量限制等),它应该编译成一个非常小的程序集。
编辑:Per @matt,在这里你去(Objective-C):
static inline UIViewAnimationOptions animationOptionsWithCurve(UIViewAnimationCurve curve) { switch (curve) { case UIViewAnimationCurveEaseInOut: return UIViewAnimationOptionCurveEaseInOut; case UIViewAnimationCurveEaseIn: return UIViewAnimationOptionCurveEaseIn; case UIViewAnimationCurveEaseOut: return UIViewAnimationOptionCurveEaseOut; case UIViewAnimationCurveLinear: return UIViewAnimationOptionCurveLinear; } }
Swift 3:
extension UIViewAnimationOptions { init(curve: UIViewAnimationCurve) { switch curve { case .easeIn: self = .curveEaseIn case .easeOut: self = .curveEaseOut case .easeInOut: self = .curveEaseInOut case .linear: self = .curveLinear } } }
你所build议的分类方法是“正确”的方法 – 你不必保证这些常数保持其价值。 从看他们是如何定义的,但是,看来你可以做
animationOption = animationCurve << 16;
如果编译器觉得好像在抱怨那样,那么可能会用到NSUInteger和UIViewAnimationOptions。
在斯威夫特你可以做
extension UIViewAnimationCurve { func toOptions() -> UIViewAnimationOptions { return UIViewAnimationOptions(rawValue: UInt(rawValue << 16)) } }
基于交换机的解决scheme存在的一个问题是,它假定不会有任何选项的组合会被传入。实践表明,可能存在假设不成立的情况。 我发现的一个例子是(至less在iOS 7上)当您获得键盘animation来为您的内容制作animation以及键盘的出现/消失。
如果你听keyboardWillShow:
或keyboardWillHide:
通知,然后得到键盘宣布它将使用的曲线,例如:
UIViewAnimationCurve curve = [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
您可能会获得值7.如果将其传递给开关函数/方法,则无法正确翻译该值,从而导致错误的animation行为。
诺亚威瑟斯庞的答案将返回正确的价值。 结合这两个解决scheme,你可能会写如下的东西:
static inline UIViewAnimationOptions animationOptionsWithCurve(UIViewAnimationCurve curve) { UIViewAnimationOptions opt = (UIViewAnimationOptions)curve; return opt << 16; }
正如挪亚指出的那样,这里的警告是,如果苹果改变了这两种types不再一致的枚举,那么这个function就会被打破。 无论如何,使用它的原因是,基于开关的选项不适用于您今天可能遇到的所有情况,而这样做。