核心动画是一套包含图形绘制、投影。动画的类集合。使用核心动画,只需要设置一餐参数比如终点和起点,剩下的核心动画为你自动完成。
CALayer简介
1、CALayer是核心动画的基础,可以做圆角、阴影、边框等效果
2、每个UIView内部都有有个layer属性
3、UIView可以响应事件,而CALayer只负责显示
4、在实现核心动画时,本质上是将CALayer中的内容转换为位图,从而便于图形硬件的操纵
5、UIView有frame、bounds、center三个属性而CALayer也有类似的属性,分别为frame、bounds、position(锚点在图层的位置)、anchorPoint(锚点在父图层的位置)
anchorPoint的默认值是(0.5,0.5),也就是anchorPoint默认在layer的中心点 frame.origin.x = position.x - anchorPoint.x * bounds.size.width; frame.origin.y = position.y - anchorPoint.y * bounds.size.height;
Layer的设计目的不是为了取代视图,因此不能基于CALayer创建一个独立的可视化组件
Layer的设计目的是提供视图的基本可视内容,从而提高动画的执行效率(除提供可视内容外,Layer不负责视图的事件响应、内容绘制等工作,同时Layer不能参与到响应者链条中)
- (void)viewDidLoad {
[super viewDidLoad];
UIView *view = [[UIView alloc]initWithFrame:CGRectMake(20, 20, 300, 200)];
view.backgroundColor = [UIColor redColor];
[self.view addSubview:view];
//图层
//边框 (向view的内部扩展)
view.layer.borderWidth= 20;//默认是0
view.layer.borderColor = [UIColor greenColor].CGColor;
//圆角半径
view.layer.cornerRadius = 50;
//阴影
//阴影颜色 (默认黑色)
view.layer.shadowColor = [UIColor grayColor].CGColor;
//阴影偏移量 (默认是0 0)
view.layer.shadowOffset = CGSizeMake(-50, 50);
//阴影的不透明度 (默认是 0 透明)
view.layer.shadowOpacity = 1;
//内容
//__bridge: core Foundation对象(CF core text)[将cf对象的内存管理交给ARC处理]
view.layer.contents = (__bridge id _Nullable)([UIImage imageNamed:@"1.jpg"].CGImage);
// //手动管理
// CGImageRef cgImage = [UIImage imageNamed:@"1.jpg"].CGImage;
// CGImageRelease(cgImage);
// 子视图超出的部分 不显示
// view.clipsToBounds = YES;
//超出layer的部分 不显示(将阴影裁掉)
view.layer.masksToBounds = YES;
2、核心动画(Core Animation)
开发步骤:(1)初始化一个动画对象(CAAnimation)并设置一些动画相关属性 (2)添加动画对象到层中,开始执行动画 Core Animation的动画执行过程都是在后台操作的,不会阻塞主线程
-(void)scaleAnimation{
// 1 CAanimation
//bounds transform
//KeyPath:指定layer的一个属性值,通过修改该属性值达到动画的效果
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
//2 设置属性
//1>动画的起始值
animation.fromValue = @0.5;
//2>动画的结束值
animation.toValue = @3;
//--------- CAMediaTiming----------
//3>动画的持续时间
animation.duration = 3;
//4>自动回放 (多花一倍时间)
-(void)scaleAnimation{
// 1 CAanimation
//bounds transform
//KeyPath:指定layer的一个属性值,通过修改该属性值达到动画的效果
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
//2 设置属性
//1>动画的起始值
animation.fromValue = @0.5;
//2>动画的结束值
animation.toValue = @3;
//--------- CAMediaTiming----------
//3>动画的持续时间
animation.duration = 3;
//4>自动回放 (多花一倍时间)
// animation.autoreverses = YES;
//5>动画完成后移除动画 (如果不移除动画,需要和填充方式一起使用)
animation.removedOnCompletion = NO; //(默认是yes)
//6>填充方式
animation.fillMode = kCAFillModeForwards;
// animation.fillMode = kCAFillModeBackwards;
/*
kCAFillModeForwards:保留动画结束后的效果
kCAFillModeBackwards:动画开始之前,会提前进入动画开始的效果(开延时才可以看出)
kCAFillModeBoth:2者都有
kCAFillModeRemoved:2者都没有(默认)
*/
//7>beginTime:开始时间 (延迟一秒之后执行动画)
// animation.beginTime = CACurrentMediaTime()+1;
//8>timeOffset 时间偏移量 (开始执行第2秒的动画,执行到指定的持续时间为止)
// animation.timeOffset = 2;
//9>repeatCount:重复次数
animation.repeatCount = 2;
//10>repeatDuration:重复的总时间 (如果和重复次数有冲突,遵循从重复时间)
animation.repeatDuration =4;
//11>speed:动画的速度 (和持续时间冲突)
animation.speed =.3;
//3 将动画对象添加到layer上面
//key:标示
//animation对象在这copy一份;所以属性要写在添加之前
[self.myImageView.layer addAnimation:animation forKey:@"animation"];
}
/*
.duration:动画的持续时间
·repeatCount:重复次数,无限循环可以设置HUGE_VALF或者MAXFLOAT
·repeatDuration:重复时间
·fillMode:决定当前对象在非active时间段的行为。比如动画开始之前或者动画结束之后
·beginTime:可以用来设置动画延迟执行时间,若想延迟2s,就设置为CACurrentMediaTime()+2, CACurrentMediaTime()为图层的当前时间
*/
(3)CAAnimation的子类(CAPropertyAnimation) 属性说明: keyPath:通过制动CALayer的一个属性名称为keyPath(NSString类型),并且对CALayer的这个属性的值进行修改,达到相应的动画效果。
1)基本动画,是CAPropertyAnimation的子类CABasicAnimation
属性说明:fromKeyValue:keyPath相应属性的初始值 toValue:keyPath相应属性的结束值
动画过程说明: 随着动画的进行,在长度为duartion的持续时间中,keyPath相应属性的值从fromValue渐渐地变为toValue
keyPath的内容是CALayer的可动画Animation属性 如果fillMode=kCAFillModeForwards同时removedOnComletion=NO,那么在动画执 行完毕后,图层会保持显示动画执行后的状态。但在实质上,图层的属性值还是动画执行前的 初始值,并没有真正被改变。
-(void)rorateAnimation{
//1 创建动画
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
//2 设置
animation.duration = 3;
animation.fromValue = @0;
animation.toValue = @M_LN2;
animation.repeatCount = 100;
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeBoth;
//3 添加
[self.myImageView.layer addAnimation:animation forKey:nil];
}
2)关键帧动画,也是CAPropertyAnimation的子类,与CABasicAnimation的区别是 ·CABasicAnimation只能从一个数值(fromValue)变到另一个数值(toValue),而 CAKeyframeAnimation会使用一个NSArray保存这些数值
·属性说明: ·values:上述的NSArray对象。里面的元素称为“关键帧”(keyframe)。动画对象会在指定 的时间(duration)内,依次显示values数组中的每一个关键帧
·path:可以设置一个CGPathRef、CGMutablePathRef,让图层按照路径轨迹移动。path 只对CALayer的anchorPoint和position起作用。如果设置了path,那么values将被忽略
·keyTimes:可以为对应的关键帧指定对应的时间点,其取值范围为0到1.0,keyTimes中的 每一个时间值都对应values中的每一帧。如果没有设置keyTimes,各个关键帧的时间是平分的
·CABasicAnimation可看做是只有2个关键帧的CAKeyframeAnimation
-(void)moveAction{
//1 创建动画对象
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
//2 设置
animation.duration = 3;
/*
//关键帧
CGPoint p0 = self.myImageVIew.center;
NSValue *v0 = [NSValue valueWithCGPoint:p0];
CGPoint p1 = CGPointMake(300, 100);
NSValue *v1 = [NSValue valueWithCGPoint:p1];
CGPoint p2 = CGPointMake(200, 400);
NSValue *v2 = [NSValue valueWithCGPoint:p2];
animation.values = @[v0,v1,v2,v0];
*/
//path:沿着路径移动
CGMutablePathRef path = CGPathCreateMutable();
CGPoint startP = self.myImageVIew.center;
CGPathMoveToPoint(path, NULL, startP.x, startP.y);
//
// CGPoint cp = CGPointMake(200, 0);
// CGPoint cp1 = CGPointMake(200, 400);
// CGPoint cp2 = CGPointMake(300, 500);
//
// //绘制贝塞尔曲线
// CGPathAddCurveToPoint(path, NULL, cp.x, cp.y, cp1.x, cp1.y, cp2.x, cp2.y);
//设置动画的执行路径
animation.path = path;
//3 添加
[self.myImageVIew.layer addAnimation:animation forKey:@"move"];
//注意:release
CGPathRelease(path);
}