情诗网 >情感扎心 > 正文

一头扎进iOS核心动画(一)

来源:情诗网    2020-12-06    分类:情感扎心

记录一下学习的笔记

核心动画

Core Animation简介

核心动画继承结构

Snip20160324_13.png

基本动画

一、位移动画

效果图: 注意,这里动画执行完毕后,状态是会还原到开始动画的位置,我们可以继续点击屏幕,再次执行动画。可以使用removedOnCompletionfillMode控制动画执行完毕后的状态,详情继续往下看。

1.gif
 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    // 1、初始化动画对象
    CABasicAnimation *anim = [CABasicAnimation animation];
    
    // 2、设置属性值
    anim.keyPath = @"transform.translation.x";
    anim.toValue = @100;
  
    // 一个layer里面可能有多个动画,forKey可以方便管理
    [self.blueView.layer addAnimation: anim forKey: nil];
}

看以下的代码,分别在动画开始前打印了layerposition的值,动画执行完毕后也打印了layerposition的值,不过要设置一下动画的代理。

     - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:      (UIEvent *)event
{
        NSLog(@"开始时position的值:%@", NSStringFromCGPoint(self.blueView.layer.position));
        // 1、初始化动画对象
        CABasicAnimation *anim = [CABasicAnimation animation];
    
        // 2、设置属性值
        anim.keyPath = @"transform.translation.x";
        anim.toValue = @100;
    
        // 3、动画完成后是否删除动画
        anim.removedOnCompletion = NO;
        anim.fillMode = kCAFillModeForwards;
        anim.delegate = self;
        //  anim.fillMode = @"forwards";    // 也是支持字符串的
        //  anim.fillMode = @"backwards";   // 默认的
  
    
        // 一个layer里面可能有多个动画,forKey可以方便管理
        [self.blueView.layer addAnimation: anim forKey: nil];
}

- (void)animationDidStart:(CAAnimation *)anim
{
    NSLog(@"开始动画");
}

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
    NSLog(@"执行后position的值:%@", NSStringFromCGPoint(self.blueView.layer.position));
}

效果图:
点击屏幕,layer停留在动画结束的那一位置。

1.gif

实际的position的值并没有改变

Snip20160324_7.png

二、心跳动画

效果图:

1.gif
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    // 创建动画对象
    CABasicAnimation *anim = [CABasicAnimation animation];

    anim.keyPath = @"transform.scale";  // transform.scale 表示长和宽都缩放
    anim.toValue = @0;                  // @0 缩放到最小
    
    anim.duration = 0.5;                // 设置动画执行时间
    anim.repeatCount = MAXFLOAT;        // MAXFLOAT 表示动画执行次数为无限次
    
    anim.autoreverses = YES;            // 控制动画反转 默认情况下动画从尺寸1到0的过程中是有动画的,但是从0到1的过程中是没有动画的,设置autoreverses属性可以让尺寸0到1也是有过程的
    
    [self.imageView.layer addAnimation: anim forKey: nil];
}

桢动画

CApropertyAnimation的子类,跟CABasicAnimation的区别是:CABasicAnimation只能从一个数值(fromValue)变到另一个数值(toValue),而CAKeyframeAnimation会使用一个NSArray保存这些数值, 也可以使用UIBezierPath来绘制动画路径。

属性解析:

说明:CABasicAnimation可看做是最多只有2个关键帧的CAKeyframeAnimation

一、抖动效果

效果图:

1.gif
#define angle2Radio(angle) ((angle) * M_PI / 180.0)     // 旋转角度的宏
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];

    anim.keyPath = @"transform.rotation";  // rotation.x、rotation.y与rotation.z 默认是z
    anim.values = @[@(angle2Radio(-5)), @(angle2Radio(5)), @(angle2Radio(-5))]; // 把度数转换为弧度  度数/180*M_PI
    
    anim.repeatCount = MAXFLOAT;    // 动画执行次数无限次
    
    [self.imageView.layer addAnimation: anim forKey: nil];
}

转场动画

CAAnimation的子类,用于做转场动画,能够为层提供移出屏幕和移入屏幕的动画效果。iOS比Mac OS X的转场动画效果少一点
UINavigationController就是通过CATransition实现了将控制器的视图推入屏幕的动画效果

属性解析:

效果图:

1.gif
static int _i = 1;
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{

    // 0、切换图片
    _i++;
    if (_i > 3) {
        _i = 1;
    }
    self.imageView.image = [UIImage imageNamed: [NSString stringWithFormat: @"%d", _i]];
    
    // 1、创建转场动画
    CATransition *trans = [CATransition animation];
    trans.duration = 1;
    
    // 2、设置转场类型
    trans.type = @"cude";
    
    [self.imageView.layer addAnimation: trans forKey: nil];
}
类型字符串 效果说明 关键字 方向
fade 交叉淡化过渡 YES
push 新视图把旧视图推出去 YES
moveIn 新视图移到旧视图上面 YES
reveal 将旧视图移开,显示下面的新视图 YES
cube 立体翻转效果
oglflip 上下左右翻转效果
suckEffect 收缩效果,如同一块布被抽走 NO
rippleEffect 水滴效果 NO
pageCurl 向上翻页效果
pageUnCurl 向下翻页效果
cameraIrisHollowOpen 相机镜头打开效果 NO
cameraIrisHollowClose 相机镜头关闭效果 NO

动画组

动画组,是CAAnimation的子类,可以保存一组动画对象,将CAAnimationGroup对象加入层后,组中所有动画对象可以同时并发运行。

属性说明:

一、移动、缩小同时进行的动画

效果图:

1.gif
Snip20160324_14.png
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    CABasicAnimation *anim1 = [CABasicAnimation animation];

    anim1.keyPath = @"transform.translation.y";
    anim1.toValue = @100;
    anim1.duration = 2;
    anim1.removedOnCompletion = NO;
    anim1.fillMode = kCAFillModeForwards;
    
    

    CABasicAnimation *anim2 = [CABasicAnimation animation];
    
    anim2.keyPath = @"transform.scale";
    anim2.toValue = @0.5;
    anim2.duration = 2;
    anim2.removedOnCompletion = NO;
    anim2.fillMode = kCAFillModeForwards;
    
    [self.blueView.layer addAnimation: anim1 forKey: nil];
    [self.blueView.layer addAnimation: anim2 forKey: nil];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    CAAnimationGroup *groupAnim = [CAAnimationGroup animation];
    groupAnim.duration = 2;
    groupAnim.removedOnCompletion = NO;
    groupAnim.fillMode = kCAFillModeForwards;
    
    CABasicAnimation *anim1 = [CABasicAnimation animation];
    anim1.keyPath = @"transform.translation.y";
    anim1.toValue = @100;

    CABasicAnimation *anim2 = [CABasicAnimation animation];
    anim2.keyPath = @"transform.scale";
    anim2.toValue = @0.5;
    
    groupAnim.animations = @[anim1, anim2];
    [self.blueView.layer addAnimation: groupAnim forKey: nil];
}

UIView动画和核心动画的区别和选择

区别:

选择:

热门文章