核心动画详细阐述(下)

简介: 核心动画详细阐述(下)

五.隐式动画(手动创建的CALayer才有隐式动画):也就是说自带动画,不需要加animation

  • 每一个UIView内部都默认连着一个CALayer,我们可用称这个LayerRootLayer(根层)
  • 所有的非Root Layer,也就是手动创建的CALayer对象,都存在隐式动画


下面以一个clayer的旋转为例


旋转一般会用到 角度转弧度: 角度/180.0*M_PI

宏定义: #define angle2radion(angle)  ((angle) / 180.0 * M_PI)


重点提一下:旋转的中心: layer.anchorPoint = CGPointZero;

anchorPoint的范围是(0~1,0~1);


image.png


隐式动画代码 密码: icgj


切记:非根层才能建立隐式动画(也就是自定义的CALayer)


六.时钟的制作


晓效果图如下:


image.png


在涉及到旋转的时候我们首先要确定的是它的锚点,其次是position


这里主要是运用了1.隐式动画.2.角度转弧度.3.再就是一些旋转的设置

角度转弧度
 #define angle2radion(angle)  ((angle) / 180.0 * M_PI)

时钟的代码:里面有中详细的注释  密码: b2c8


在此多数几句:如何获取系统的时间

//获取当前的系统时间
//获取当前日历对象
NSCalendar  *calendar =[NSCalendar currentCalendar];
//获取日期的组件,年月日,时分秒
//components: 需要获取日期组件
//formDate:获取哪个日期组件
//经验:以后枚举中有移位运算符(<<),一般来说我们就可以用 |  :"并" 的方式
NSDateComponents  *dateComponents = [calendar components:NSCalendarUnitSecond | NSCalendarUnitMinute | NSCalendarUnitHour | NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:[NSDate date]];

NSLog(@"小时==%ld",dateComponents.hour);

NSLog(@"分钟==%ld",dateComponents.minute);

NSLog(@"秒==%ld",dateComponents.second);


七.核心动画(介绍四个,CABasicAnimation, CAKeyframeAnimation, CATransition, CAAnimationGroup)


  • <1>.Core Animation 中文翻译为核心动画,它是一组非常强大的动画处理API,使用它可以做出非常炫酷的效果,而且往往是事半功倍,也就是说,使用少量的代码就可以实现非常强大的功能.
  • <2>.Core Animation 可以使用在Mac OS XiOS平台.
  • <3>.Core Animation 的动画执行过程都是在后台操作的,不会阻塞主线程.
  • <4>.需要注意的是:Core Animation 是直接作用在CALayer上的,并非UIView.在此也说一下UIView也有动画,其实也是在底层封装了核心动画


image.png

(1)CABasicAnimation创建动画(这里仅仅以一个view的移动为例):只能用于2个值之间


image.png


/**
   *  CABasicAnimation创建核心动画
   */
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    //创建动画
    CABasicAnimation *animation = [CABasicAnimation animation];
    //描述下修改那个属性产生动画
    animation.keyPath = @"position";
    //设置值(点转化为对象)
    animation.toValue = [NSValue valueWithCGPoint:CGPointMake(arc4random_uniform(500), arc4random_uniform(500))];
    //取消动画反弹需要2步
    //1.设置动画完成时候不要移除动画
    animation.removedOnCompletion = NO;
    //2.设置动画执行完成保持最新的效果
    animation.fillMode = kCAFillModeForwards;
    //添加动画
    [_redView.layer addAnimation:animation forKey:nil];
}

如果先个缩放就把上面的值改了就好

animation.keyPath = @"transform.scale";
 animation.toValue = @0.5;

如果想做一个心脏的话那么久设置一个一直执行动画,也可以调节动画的时间长短,下面的代码放到一个方法里面就好(可以做心脏的跳动)


二维的放大和缩小


_redVie就是一个UIImageView的类的对象


image.png

//创建动画
CABasicAnimation *animation = [CABasicAnimation animation];
//描述下修改那个属性产生动画
animation.keyPath = @"transform.scale";
//设置值
animation.toValue = @0.5;
//设置每次动画的时间
animation.duration = 1;
//如果想一直执行动画,很久
animation.repeatCount = MAXFLOAT;//表示最大次数
//取消动画反弹需要2步
//1.设置动画完成时候不要移除动画
animation.removedOnCompletion = NO;
//2.设置动画执行完成保持最新的效果
animation.fillMode = kCAFillModeForwards;
//添加动画
[_redView.layer addAnimation:animation forKey:nil];


当然我们还可以设置旋转


image.png


animation.keyPath = @"transform.rotation";
  animation.toValue = @(M_PI*2);//360旋转
  • (2).cakeyframeanimation创建帧动画


1.心脏的抖动


image.png

代码如下:

//创建动画
CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
//根据路径来走
animation.keyPath = @"transform.rotation";
//角度的设定
animation.values = @[@angle2radion(-5),@angle2radion(5),@angle2radion(-5)];
//不停地循环来抖动
animation.repeatCount = MAXFLOAT;
//添加在图层上的动画
[_heart.layer addAnimation:animation forKey:nil];


当然你也可以设置它的锚点

_heart.layer.anchorPoint = CGPointZero;(以心脏的左上为旋转的点来抖动)


2.让心脏绕着指定轨迹来做运动(用到了贝塞尔曲线):改变的是位置position


image.png


核心代码如下:

//创建动画
CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
//改变的位置
animation.keyPath = @"position";
//动画执行的时间
animation.duration = 2;
//设定转圈的路径
animation.path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(100, 200, 200, 200)].CGPath;
//重复动画
animation.repeatCount = MAXFLOAT;
//添加动画
[_heart.layer addAnimation:animation forKey:nil];


3.心脏根据画出路径来走


首先要建立一个UIView 也就是图层(画画的地方)


效果如下

image.png


心脏根据路径走的代码  密码: dq43


核心代码如下:

@property(nonatomic,strong) UIBezierPath *path;
/**
 *  手指接触屏幕的点
 */
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//touch
UITouch *touch = [touches anyObject];
//获取手指的触摸点
CGPoint pointCurrent = [touch locationInView:self];
//创建路径
UIBezierPath *path = [UIBezierPath bezierPath];
//记录路径
_path = path;
//设置起点
[path moveToPoint:pointCurrent];
}
/**
 *  手指一动的时候的点
 */
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//touch
UITouch *touch = [touches anyObject];
//获取手指的触摸点
CGPoint pointCurrent = [touch locationInView:self];
//保存每一个路径
[_path addLineToPoint:pointCurrent];
//每次一动就调用画画
[self setNeedsDisplay];
}
/**
 *  画线
 */
-(void)drawRect:(CGRect)rect
{
   [_path stroke];
}
/**
 *  手指抬起来的时候
 */
-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//创建动画
CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
animation.keyPath = @"position";
animation.duration = 2;
animation.path = _path.CGPath;
animation.repeatCount = MAXFLOAT;
//添加动画
[[[self.subviews firstObject] layer] addAnimation:animation forKey:nil];
 }


image.png

image.png

添加动画

[[[self.subviews firstObject] layer] addAnimation:animation forKey:nil];


注意:我再重复一次,动画式添加在图层上的


  • (3).转场动画CATransition


转场动画转场代码要写在一起:(切记)


效果图如下:


image.png

核心代码如下:(转场动画和转场代码要写在一起)

/**
  *  在触摸时的变化
  */
 -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    转场代码
    if(i==4)
    {
         i = 1;
    }
    NSString *imageName = [NSString stringWithFormat:@"%d.jpg",i];
    _imageView.image = [UIImage imageNamed:imageName];
    i++;
   添加转场动画
   CATransition *animation = [CATransition animation];
   animation.type = @"cube";
   animation.duration = 2;
   [_imageView.layer addAnimation:animation forKey:nil];
}

如果想看其他的效果:可以更改下面的值:

animation.type = @"cube";


image.png

转场动画代码密码: ffmy


  • (4).动画组(之前的动画只能缩放或者旋转,动画组可以实现旋转和缩放同时进行)


效果如下:


image.png


动画组

核心的代码如下:(也就是一个group来包含很多的动画组合起来的)

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
 //同时缩放,平移,旋转
 CAAnimationGroup *group = [CAAnimationGroup animation];
 group.duration = 2;
 CABasicAnimation *scale = [CABasicAnimation animation];
 scale.keyPath = @"transform.scale";
 scale.toValue = @0.5;
 CABasicAnimation *rotation = [CABasicAnimation animation];
 rotation.keyPath = @"transform.rotation";
 rotation.toValue = @(arc4random_uniform(M_PI));
 CABasicAnimation *position = [CABasicAnimation animation];
 position.keyPath = @"position";
 position.toValue = [NSValue valueWithCGPoint:CGPointMake(arc4random_uniform(200)+100, arc4random_uniform(400)+100)];
 group.animations = @[scale,rotation,position];
 //取消动画反弹需要2步
 //1.设置动画完成时候不要移除动画
 group.removedOnCompletion = NO;
 //2.设置动画执行完成保持最新的效果
 group.fillMode = kCAFillModeForwards;
 [_imageView.layer addAnimation:group forKey:nil];
}


动画组代码   密码: 4yiq

再重复一次:核心动画式加在图层上的


八.UIView与核心动画的区别


注意:


1.核心动画一切都是假象,并不会真实的改变图层的属性值.如果以后做动画的时候,不需要与用户交互,通常用核心动画(转场)


原因:当我们改变一个视图的position的时候,它的position并没有发生改变,大家可以打印一下看看(打印看看)

NSLog(@"%@",NSStringFromCGPoint(_girl.layer.position));

2.UIView动画必须通过修改属性的真实值,才有动画效果

[UIView animateWithDuration:1 animations:^{
} completion:^(BOOL finished) {
}];


目录
相关文章
|
API Android开发
Android动画基础详析 | 属性动画基础及ValueAnimator
Android动画基础详析 | 属性动画基础及ValueAnimator
|
XML 存储 Java
Android动画基础详析 | 概述、逐帧动画、视图动画(附诸多实际运行效果动图)
Android动画基础详析 | 概述、逐帧动画、视图动画(附诸多实际运行效果动图)
|
数据安全/隐私保护 iOS开发
核心动画详细阐述(上)
核心动画详细阐述
122 0
核心动画详细阐述(上)
|
iOS开发
iOS动画开发之四——核心动画编程(CoreAnimation)
iOS动画开发之四——核心动画编程(CoreAnimation)
182 0
iOS动画开发之四——核心动画编程(CoreAnimation)
|
iOS开发 容器
iOS开发CoreAnimation解读之二——对CALayer的分析(一)
iOS开发CoreAnimation解读之二——对CALayer的分析
142 0
iOS开发CoreAnimation解读之二——对CALayer的分析(一)
|
iOS开发
iOS开发CoreAnimation解读之二——对CALayer的分析(二)
iOS开发CoreAnimation解读之二——对CALayer的分析
211 0
iOS开发CoreAnimation解读之二——对CALayer的分析(二)
|
iOS开发
iOS动画开发之五——炫酷的粒子效果(二)
iOS动画开发之五——炫酷的粒子效果
338 0
iOS动画开发之五——炫酷的粒子效果(二)
|
存储 iOS开发 计算机视觉
iOS开发CoreAnimation解读之一——初识CoreAnimation核心动画编程
iOS开发CoreAnimation解读之一——初识CoreAnimation核心动画编程
177 0
iOS开发CoreAnimation解读之一——初识CoreAnimation核心动画编程
|
iOS开发
iOS动画开发之五——炫酷的粒子效果(一)
iOS动画开发之五——炫酷的粒子效果
377 0