我想知道是否有办法在应用程序中快速使用更多不同的计时功能。例如,使用Robert Penner's,许多工具包暴露它们,我很惊讶Apple没有。
基本上是一种让基于块的命令像animateWithDuration一样灵活的方法:delay:options:animations:completion:in UIView。
我想出了这个解决方案,很高兴知道是否有更好的选择。
// UIView+CustomTimingFunction.h
#import <UIKit/UIKit.h>
typedef enum {
CustomTimingFunctionDefault,
CustomTimingFunctionLinear,
CustomTimingFunctionEaseIn,
CustomTimingFunctionEaseOut,
....
} CustomTimingFunction;
@interface UIView (CustomTimingFunction)
- (void)animateProperty:(NSString *)property from:(id)from to:(id)to withDuration:(NSTimeInterval)duration customTimingFunction:(CustomTimingFunction)customTimingFunction competion:(void (^)(void))competion;
@end
和
// UIView+CustomTimingFunction.m
#import "UIView+CustomTimingFunction.h"
@implementation UIView (CustomTimingFunction)
- (void)animateProperty:(NSString *)property from:(id)from to:(id)to withDuration:(NSTimeInterval)duration customTimingFunction:(CustomTimingFunction)customTimingFunction competion:(void (^)(void))competion
{
[CATransaction begin]; {
[CATransaction setCompletionBlock:competion];
if([property isEqualToString:@"frame"]){
CGRect fromRect = [from CGRectValue];
CGPoint fromPosition = CGPointMake(CGRectGetMidX(fromRect), CGRectGetMidY(fromRect));
CGRect toRect = [to CGRectValue];
CGPoint toPosition = CGPointMake(CGRectGetMidX(toRect), CGRectGetMidY(toRect));
CABasicAnimation *positionAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
positionAnimation.timingFunction = [[self class] functionWithType:customTimingFunction];
positionAnimation.fromValue = [NSValue valueWithCGPoint:fromPosition];
positionAnimation.toValue = [NSValue valueWithCGPoint:toPosition];
CABasicAnimation *boundsAnimation = [CABasicAnimation animationWithKeyPath:@"bounds"];
boundsAnimation.timingFunction = [[self class] functionWithType:customTimingFunction];
boundsAnimation.fromValue = from;
boundsAnimation.toValue = to;
CAAnimationGroup * group =[CAAnimationGroup animation];
group.removedOnCompletion=NO;
group.fillMode=kCAFillModeForwards;
group.animations = @[positionAnimation,boundsAnimation];
group.duration = duration;
[self.layer addAnimation:group forKey:property];
}else{
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:property];
animation.duration = duration;
animation.timingFunction = [[self class] functionWithType:customTimingFunction];
animation.fillMode = kCAFillModeForwards;
animation.removedOnCompletion = NO;
animation.fromValue = from;
animation.toValue = to;
[self.layer addAnimation:animation forKey:animation.keyPath];
}
} [CATransaction commit];
}
+(CAMediaTimingFunction *)functionWithType:(CustomTimingFunction)type
{
switch (type) {
case CustomTimingFunctionDefault:
return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault];
break;
case CustomTimingFunctionLinear:
return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
break;
case CustomTimingFunctionEaseIn:
return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
break;
case CustomTimingFunctionEaseOut:
return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
break;
case CustomTimingFunctionEaseInOut:
return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
break;
....
}
NSLog(@"Couldn't find CustomTimingFunction, will return linear");
return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
}
@end
谢谢!