CoreAnimation

作者: 南镇s | 来源:发表于2015-08-24 22:27 被阅读1599次

    今天抽空大致介绍iOS开发中常见动画的使用,及注意点:
    下面以一张图片总结一下iOS开发中常用动画,

    流程.png

    CALayer:隐式动画

    CATransaction :NSObject(区分下面的CATransition,他是继承CATran)

    [CATransaction begin];
     
    [CATransaction setDisableActions:!enableAnimation.isOn];
    
    [CATransaction setAnimationDuration:animationDuration.value];
    
    [_layer setCornerRadius:[_layer cornerRadius]==0?30:0];
    
    [_layer setBorderWidth:[_layer borderWidth]==0?5:0];
    
    [_layer setBorderColor:[UIColor redColor].CGColor];
    
    [CATransaction commit];
    

    常用方法

    • (void)begin;
    • (void)commit;
    • (void)flush;
    • (void)lock;
    • (void)unlock;
    隐式动画.png
    [UIView beginAnimations:@"animationID" context:nil];
    
    [UIView setAnimationDuration:animationDuration.value];
    
    [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
    
    [UIView setAnimationRepeatAutoreverses:enableAnimation.isOn];
    [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:image cache:YES];
    
    [UIView commitAnimations];
    

    常用方法:

    setAnimationDuration

    + (void)beginAnimations:(NSString *)animationID context:(void *)context;  
    + (void)commitAnimations; 
    
    
    + (void)setAnimationDuration:(NSTimeInterval)duration;              // default = 0.2
    + (void)setAnimationDelay:(NSTimeInterval)delay;    // default=now ([NSDate date])
    + (void)setAnimationCurve:(UIViewAnimationCurve)curve;              // default = UIViewAnimationCurveEaseInOut
    + (void)setAnimationRepeatCount:(float)repeatCount;    
    + (void)setAnimationTransition:(UIViewAnimationTransition)transition forView:(UIView *)view cache:(BOOL)cache;  // current limitation - only one per begin/commit block
    

    Block动画:

    [UIView animateWithDuration:animationDuration.value delay:.5 options:UIViewAnimationOptionCurveEaseOut animations:^(void){
    
    [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:image cache:YES];
                } completion:^(BOOL finish){
                    animationDurationLabel.text = @"动画结束";
                }];
    

    常用方法

    + (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion NS_AVAILABLE_IOS(4_0);
    
    + (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion NS_AVAILABLE_IOS(4_0); // delay = 0.0, options = 0
    
    UIViewKeyframeAnimations分类(非正式协议):
    
    + (void)animateKeyframesWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewKeyframeAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion NS_AVAILABLE_IOS(7_0);
    
    + (void)addKeyframeWithRelativeStartTime:(double)frameStartTime relativeDuration:(double)frameDuration animations:(void (^)(void))animations NS_AVAILABLE_IOS(7_0); // start time and duration are values between 0.0 and 1.0 specifying time and duration relative to the overall time of the keyframe animation
    

    三:核心动画

    ![核心动画.png](https://img.haomeiwen.com/i652450/9a4b98253c83f877.png?imageMogr2/auto-orient/strip|imageView2/2/w/1240)
    
    核心动画中最基本的属性与方法
    
    + (instancetype)animation;
    + (id)defaultValueForKey:(NSString *)key;
    - (BOOL)shouldArchiveValueForKey:(NSString *)key;
    @property(strong) CAMediaTimingFunction *timingFunction;
    @property(strong) id delegate;
     
    
    非正式协议:
    
    - (void)animationDidStart:(CAAnimation *)anim;
    - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;
     @property(getter=isRemovedOnCompletion) BOOL removedOnCompletion;
    下面也是在官方文档中关于核心动画的一段话
    
    CAAnimation is an abstract animation class. It provides the basic support for the CAMediaTiming and CAAction protocols. To animate Core Animation layers or Scene Kit objects, create instances of the concrete subclasses CABasicAnimation, CAKeyframeAnimation, CAAnimationGroup, or CATransition.
    

    CATransition(转场动画)

    继承自:CAAnimation

    CATransition *transtion = [CATransition animation];
    
    [transtion setStartProgress:.2];
    
    [transtion setEndProgress:.8];
    
    transtion.duration = animationDuration.value;
    
    [transtion setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
    
    [transtion setType:@"rippleEffect"];
    
    [transtion setSubtype:kCATransitionFromTop];
    
    [image.layer addAnimation:transtion forKey:@"transtionKey"];
    
    转场动画.png

    常用属性

    @property(copy) NSArray *animations;
    @property float startProgress;
    @property float endProgress;
    @property(strong) id filter;
    duration:设置动画时间
    type:subtype:typetimingFunction ,,(),

    转场类型type:

    Fade = 1,                   //淡入淡出
    Push,                       //推挤
    Reveal,                     //揭开
    MoveIn,                     //覆盖
    Cube,                       //立方体
    SuckEffect,                 //吮吸(水滴)
    OglFlip,                    //翻转
    RippleEffect,               //波纹
    

    (默认以父类为参照,所以一般我们使用一个和子控件一样大的父控件来修改这个效果)
    PageCurl, //翻页
    PageUnCurl, //反翻页
    CameraIrisHollowOpen, //开镜头
    CameraIrisHollowClose, //关镜头
    CurlDown, //下翻页
    CurlUp, //上翻页
    FlipFromLeft, //左翻转
    FlipFromRight, //右翻转
    转场子类型subtype:

    kCAMediaTimingFunctionLinear 线性即匀速
    kCAMediaTimingFunctionEaseIn 先慢后快
    kCAMediaTimingFunctionEaseOut 先快后慢
    kCAMediaTimingFunctionEaseInEaseOut 先慢后快再慢
    kCAMediaTimingFunctionDefault 实际效果是动画中间比较快

    注意:转场动画与转场代码必须写在一起,否则无效
    
    CAPropertyAnimation动画
    
    CAPropertyAnimation(属性动画),是后面两个动画的父类
    
    继承自:CAAnimation
    
    CAPropertyAnimation *pro = [CAPropertyAnimation animation];
    
    pro.additive = YES;
    
    pro.cumulative = YES;
    
    pro.valueFunction = kCAValueFunctionScaleX;
    
    [image.layer addAnimation:pro forKey:AnimationKey]
    

    常用属性

    • (instancetype)animationWithKeyPath:(NSString *)path;
      @property(copy) NSString *keyPath;
      @property(getter=isAdditive) BOOL additive;
      @property(getter=isCumulative) BOOL cumulative;
      @property(strong) CAValueFunction *valueFunction;

    CABasicAnimation(基本动画)

    继承自;CAPropertyAnimation

    CABasicAnimation *basic = [CABasicAnimation     animationWithKeyPath:@"transform.scale"];
    
    [basic setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];
    
    [basic setFromValue:[NSNumber numberWithFloat:1]];
    
    [basic setToValue:[NSNumber numberWithFloat:.3]];
    
    [basic setDuration:animationDuration.value];
    
    [basic setDelegate:self];
    
    [image.layer addAnimation:basic forKey:AnimationKey];
    

    基本属性

    @property(strong) id fromValue;
    @property(strong) id toValue;
    @property(strong) id byValue;

    基本动画.png

    CAKeyframeAnimation(关键帧)

    继承自;CAPropertyAnimation

    1):values->
    
    CAKeyframeAnimation *keyframe = [CAKeyframeAnimation animationWithKeyPath:@"borderWidth"];
    
    keyframe.values = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0],
    
    [NSNumber numberWithFloat:5],
    
    [NSNumber numberWithFloat:10],
    
    [NSNumber numberWithFloat:15],nil];
    
    // keyframe.values = @[@12, @-12, @12];
    
    keyframe.repeatCount = MAXFLOAT;
    
    keyframe.autoreverses = enableAnimation.isOn;
    
    keyframe.duration = animationDuration.value;
    
    [image.layer addAnimation:keyframe forKey:AnimationKey];
    
    2):paths->
    
    UIBezierPath *path = [UIBezierPath bezierPath];
    
           // [path moveToPoint:image.frame.origin];
    
    [path moveToPoint:CGPointMake(image.frame.origin.x + image.frame.size.width/2, image.frame.origin.y + image.frame.size.height/2)];
    
    [path addLineToPoint:CGPointMake(image.frame.origin.x + image.frame.size.width/2,400)];
    
    [path addLineToPoint:CGPointMake(20, 400)];
    
    CAKeyframeAnimation *keyframe = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    
    keyframe.path = path.CGPath;
    
    keyframe.duration = animationDuration.value;
    
    [image.layer addAnimation:keyframe forKey:AnimationKey];
    
    关键帧-抖动.png

    常见属性

    @property(copy) NSArray *values;
    @property CGPathRef path;
    @property(copy) NSArray *keyTimes;
    @property(copy) NSArray *timingFunctions;
    @property(copy) NSString *calculationMode;
    @property(copy) NSArray *tensionValues;
    @property(copy) NSArray *continuityValues;
    @property(copy) NSArray *biasValues;
    @property(copy) NSString *rotationMode;

    CAAnimationGroup(动画组)

    继承自:CAAnimation

    CAAnimationGroup *group = [CAAnimationGroup animation];
    
    CABasicAnimation *basic = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
    
    [basic setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];
    
    [basic setFromValue:[NSNumber numberWithFloat:1]];
    
    [basic setToValue:[NSNumber numberWithFloat:.3]];
    
    CAKeyframeAnimation *keyframe = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.x"];
    
    keyframe.values = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0],[NSNumber numberWithFloat:M_PI], nil];
    
    [group setDuration:animationDuration.value];
    
    [group setAnimations:[NSArray arrayWithObjects:basic,keyframe, nil]];
    
    [image.layer addAnimation:group forKey:AnimationKey];
    

    常见属性

    @property(copy) NSArray *animations;
    @property(copy) NSString *fillMode;
    fillMode

    kCAFillModeForwards
    kCAFillModeBackwards
    kCAFillModeBoth
    kCAFillModeRemoved

    UIView动画与核心动画的区别,及使用注意的地方:

    1:核心动画的一切都是假象,并不会真实的修改layer对应的属性
    2:UIView必须修改真实属性的值

    使用-》
    只要不需要与用户交互就使用核心动画,如果需要与用户交互就使用UIView动画
    核心动画的使用场景:转场(核心动画包装的转场动画足够强大)

    3D动画

    下面来电更酷的3D动画(结合以上技术)

    [UIView animateWithDuration:animationDuration.value animations:^{
    
                    [UIView setAnimationRepeatCount:MAXFLOAT];
    
                    [UIView setAnimationRepeatAutoreverses:enableAnimation.isOn];
    
                    CATransform3D transform = CATransform3DMakeTranslation(0, -150, 0);
    
                    CATransform3D trans = CATransform3DScale(transform, 1.5, 1.5, 10);
    
                    [label.layer setTransform:trans];
    
                } completion:^(BOOL finished) {
    
                    animationDurationLabel.text = @"finished";
    
                }];
    

    CABasicAnimation

    CABasicAnimation *basic = [CABasicAnimation 
    
    animationWithKeyPath:@"transform.scale"];
    
    [basic setDuration:animationDuration.value];
    
    [basic setRepeatCount:MAXFLOAT];
    
    [basic setAutoreverses:enableAnimation.isOn];
    
    NSValue *valueForm = [NSValue 
    
    valueWithCATransform3D:CATransform3DIdentity];
    
    CATransform3D transTo = CATransform3DMakeScale(.5, .5, 0);
    
    NSValue *valueTo = [NSValue valueWithCATransform3D:transTo];
    
    [basic setFromValue:valueForm];
    
    [basic setToValue:valueTo];
    
    [image.layer addAnimation:basic forKey:AnimationKey];
    

    CAKeyframeAnimation

    CAKeyframeAnimation *keyframe = [CAKeyframeAnimation 
    
    animationWithKeyPath:@"transform.scale"];
    
    [keyframe setRepeatCount:MAXFLOAT];
    
    [keyframe setDuration:animationDuration.value];
    
    [keyframe setAutoreverses:enableAnimation.isOn];
    
    CATransform3D transForm = CATransform3DIdentity;
    
    CATransform3D transTo = CATransform3DMakeScale(.5, .5, 0);
    
    NSValue *valueForm = [NSValue 
    
    valueWithCATransform3D:transForm];
    
    NSValue *valueTo = [NSValue valueWithCATransform3D:transTo];
    
    [keyframe setValues:[NSArray 
    
    arrayWithObjects:valueTo,valueForm,nil]];
    
    [image.layer addAnimation:keyframe forKey:AnimationKey];
    

    CABasicAnimation

    CABasicAnimation *basic = [CABasicAnimation 
    
    animationWithKeyPath:@"transform"];
    
    [basic setRepeatCount:MAXFLOAT];
    
    [basic setDuration:animationDuration.value];
    
    [basic setAutoreverses:enableAnimation.isOn];
    
    NSValue *valueForm = [NSValue 
    
    valueWithCATransform3D:CATransform3DIdentity];
    
    CGAffineTransform affine = CGAffineTransformMakeTranslation(0, 
    -150);
    
    CATransform3D t = CATransform3DMakeAffineTransform(affine);
    
    CATransform3D trans = CATransform3DScale(t, 1.5, 1.5, 10);
    
    NSValue *valueTo = [NSValue valueWithCATransform3D:trans];
    
    [basic setFromValue:valueForm];
    
    [basic setToValue:valueTo];
    
    [label.layer addAnimation:basic forKey:AnimationKey];
    

    3D弹出和隐藏动画效果:

        //使用关键帧-3D动画实现按钮的弹出效果
    CAKeyframeAnimation *popAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
    
    popAnimation.duration = 0.4;
    
    popAnimation.values = @[[NSValue valueWithCATransform3D:CATransform3DMakeScale(0.01f, 0.01f, 1.0f)],
    
    [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.1f, 1.1f, 1.0f)],
    
    [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.9f, 0.9f, 1.0f)],
    
    [NSValue valueWithCATransform3D:CATransform3DIdentity]];
    
    popAnimation.keyTimes = @[@0.2f, @0.5f, @0.75f, @1.0f];
    
    popAnimation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],
    
    [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],
    
    [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
    
    [self.layer addAnimation:popAnimation forKey:nil];
    

    //使用关键帧动画实现隐藏效果

    CAKeyframeAnimation *hideAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
    
    hideAnimation.duration = 0.4;
    
    hideAnimation.values = @[[NSValue 
    
    valueWithCATransform3D:CATransform3DMakeScale(1.1f, 1.1f, 1.0f)],
    
    [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.0f, 1.0f, 1.0f)],
    
    [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.00f, 0.00f, 0.00f)]];
    
    hideAnimation.keyTimes = @[@0.2f, @0.5f, @0.75f];
    
    hideAnimation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],
    
    [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],
    
    [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
    
    hideAnimation.delegate = self;
    
    [self.layer addAnimation:hideAnimation forKey:nil];
    

    注意:核心动画中有一个协议需要注意的:CAMediaTiming

    下面是协议对应的一些属性(方法)

    @property CFTimeInterval beginTime;
    @property CFTimeInterval duration;
    @property float speed;
    @property CFTimeInterval timeOffset;
    @property float repeatCount;
    @property CFTimeInterval repeatDuration;
    @property BOOL autoreverses;
    @property(copy) NSString *fillMode;

    相关文章

      网友评论

      本文标题:CoreAnimation

      本文链接:https://www.haomeiwen.com/subject/kqcpqttx.html