1.简介
Core Animation(核心动画)使用它能做出非常炫丽的动画效果,Core Animation是跨平台的,可以用在Mac OS X和iOS平台。动画执行过程都是在后台操作的,不会阻塞主线程。是直接作用在CALayer上的。
主要提供四种动画:基本动画、关键帧动画、动画组、转场动画
注意:核心动画只有动画,位置是不会变得。
思维导图:
2.动画类型
1.基础动画(CABasicAnimation)及动画属性设置
创建基础动画
//CABasicAnimation
CABasicAnimation *basAni = [CABasicAnimation animationWithKeyPath:@"position"];
常用key的值的取值:
key | 描述 |
---|---|
position | 位置,中心点变化,CGRect类型 |
transform.scale | 大小, 比例变化,NSNumber |
transform.scale.x | 大小, 宽比例变化,NSNumber |
transform.scale.y | 大小, 高比例变化,NSNumber |
bounds | 大小,CGRect类型 |
transform.rotation.x | 角度, 绕x轴转,NSNumber |
transform.rotation.y | 角度, 绕y轴转,NSNumber |
transform.rotation.z | 角度, 绕z轴转,NSNumber |
opacity | 透明度,NSNumber |
cornerRadius | 边角,NSNumber |
backgroundColor | 颜色,CGColor前加(id) |
设置动画开始值,和动画结束值(CABasicAnimation)
//值要对应animationWithKeyPath里面key的值类型
//开始值
basAni.fromValue = [NSValue valueWithCGPoint:CGPointZero];
//结束值
basAni.toValue = [NSValue valueWithCGPoint:CGPointMake(375, 667)];
设置动画属性(CAMediaTiming)
//设置动画的开始时间结束时间
basAni.beginTime = CACurrentMediaTime() + 1;
//设置动画的持续时间(单次的)
basAni.duration = 5;
//设置动画的重复次数
basAni.repeatCount = LONG_MAX;
//设置动画的重复时间
//basAni.repeatDuration = 1;
//设置动画的自动翻转
basAni.autoreverses = YES;
//设置时光流速(速率)
basAni.speed = 3;
//设置时光偏移量(开始的位置时动画执行了3秒之后的位置)
//basAni.timeOffset = 3;
//使用beginTime speed timeOffset设置动画暂停和继续
//设置动画在非active内的行为,开始之前结束之后
basAni.fillMode = kCAFillModeBoth;
fillMode的值:
值 | 描述 |
---|---|
KCAFillModeForwards | 结束后保持动画最终状态 |
KCAFillModeBackwards | 将动画加入layer,layer就初始化准备开始动画 |
KCAFillModeBoth | 以上两种状态的合成状态 |
KCAFillModeRemoved | 默认值,开始前和结束后对layer没有影响 |
将动画添加到view的layer上
[self.blueView.layer addAnimation:basAni forKey:@"base"];
设置动画属性及代理(CAAnimation)
//设置动画结束以后,是否移除
basAni.removedOnCompletion = NO;
监听动画的开始和结束
//设置委托,能够获取动画开始和结束,iOS10要声明协议哦<CAAnimationDelegate>
basAni.delegate = self;
//协议方法
- (void)animationDidStart:(CAAnimation *)anim {
NSLog(@"动画开始");
}
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
NSLog(@"动画结束");
}
用时光流速和时光偏移量控制动画暂停/开始
int count = 0;
- (IBAction)btnPress:(UIButton *)sender {
count ++;
if (count % 2 == 1) {
_redView.layer.speed = 0;
_redView.layer.timeOffset = CACurrentMediaTime() - _redView.layer.beginTime;
} else {
_redView.layer.speed = 1;
_redView.layer.beginTime = CACurrentMediaTime() - _redView.layer.timeOffset;
_redView.layer.timeOffset = 0;
}
}
一个layer可以添加多个动画
CABasicAnimation *basAni2 = [CABasicAnimation animationWithKeyPath:@"bounds"];
basAni2.removedOnCompletion = NO;
basAni2.fromValue = [NSValue valueWithCGRect:CGRectMake(0, 0, 100, 100)];
basAni2.toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, 300, 300)];
basAni2.duration = 5;
[self.redView.layer addAnimation:basAni2 forKey:@"bas2"];
关键帧动画( CAKeyframeAnimation)
1.移动
创建动画
CAKeyframeAnimation *keyFrame = [CAKeyframeAnimation animationWithKeyPath:@"position"];
设置动画的路径
//position是CGPoint类型的,数组里面需要放对象类型,所以,用NSValue转换。数组里面放三帧,动画按照这三个坐标移动。
keyFrame.values = @[[NSValue valueWithCGPoint:_animationView.layer.position],[NSValue valueWithCGPoint:CGPointMake(arc4random_uniform(200), arc4random_uniform(300))],[NSValue valueWithCGPoint:CGPointMake(arc4random_uniform(200), arc4random_uniform(300))]];
数组表示经过每一帧的时间,数组中的值必须从小到大,最小值为0,最大值为1
keyFrame.keyTimes = @[@0.5,@0.9999,@1];
所有的核心动画都可以用CAMediaTiming、CAAnimation进行设置。如:
keyFrame.duration = 2;
keyFrame.removedOnCompletion = NO;
keyFrame.fillMode = kCAFillModeForwards;
....
....
....
核心动画不会影响layer的位置,若要在动画完成后接着动画完成后的位置开始动画,需要手动改变layer的位置
//1.设置委托,
keyFrame.delegate = self;
//2.设置属性
keyFrame.removedOnCompletion = NO;
keyFrame.fillMode = kCAFillModeForwards;
//3.实现动画结束的协议方法
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
CAKeyframeAnimation *keyFrame = (CAKeyframeAnimation *)anim;
//4.在动画结束后改变动画的位置
_animationView.layer.position = [[keyFrame.values lastObject] CGPointValue];
NSLog(@"%@",NSStringFromCGRect(_grayView.frame));
}
添加动画
[_animationView.layer addAnimation:keyFrame forKey:@"keyFrame"];
2.抖动
抖动,就是以Z轴为轴心,来回小幅度旋转。z轴是垂直于屏幕的轴
//创建动画,绕Z轴旋转
CAKeyframeAnimation *shake = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"];
//设置动画重复次数
shake.repeatCount = MAXFLOAT;
//设置动画原路返回
shake.autoreverses = YES;
//设置动画帧数,-10度到10度,(ANGLE(-10)为宏定义计算角度ANGLE(x) M_PI/180*x
shake.values = @[@(ANGLE(-10)),@(ANGLE(10))];
//设置动画时间
shake.duration = .05;
//添加动画
[_animationView.layer addAnimation:shake forKey:@"shake"];
3.路径
绕一个路径移动
//创建动画
CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
//动画时间
pathAnimation.duration = 2;
//重复次数
pathAnimation.repeatCount = 1;
//创建path
CGMutablePathRef path = CGPathCreateMutable();
//为path赋值,参数1.path 参数2.仿射变化 参数3.路径。
CGPathAddRect(path, nil, self.view.bounds);
pathAnimation.path = path;
//释放path
CGPathRelease(path);
[_animationView.layer addAnimation:pathAnimation forKey:@"path"];
3组动画( CAAnimationGroup)
将多个动画放入数组,一起执行动画
///创建三个动画
CABasicAnimation *scale=[CABasicAnimation animationWithKeyPath:@"transform.scale"];
scale.fromValue=@1.0;
scale.toValue=@0.5;
CABasicAnimation *opcityAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
opcityAnimation.fromValue = @1;
opcityAnimation.toValue = @0.5;
CAKeyframeAnimation *shakeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"];
CGFloat angel = M_PI_4 / 8;
shakeAnimation.duration = .3;
[shakeAnimation setValues:@[@(angel), @(-angel), @(angel)]];
//创建组动画
CAAnimationGroup *group = [CAAnimationGroup animation];
//将三个动画放入数组
group.animations = @[scale,opcityAnimation,shakeAnimation];
group.repeatCount = MAXFLOAT;
//设置时间
group.duration = 1;
//添加动画
[_animationView.layer addAnimation:group forKey:@"group"];
4转场动画
//创建动画
CATransition *transition=[CATransition animation];
//动画类型,类型系统有四种,私有api 12种
transition.type=kCATransitionFade;
//方向,四种
transition.subtype=kCATransitionFromLeft;
//动画的开始百分比
transition.startProgress=0.0;
//动画的结束百分比
transition.endProgress=1.0;
//添加动画
[self.view.layer addAnimation:transition forKey:@"transition"];
//转场
[self.view exchangeSubviewAtIndex:0 withSubviewAtIndex:1];
动画类型
类型 | 描述 |
---|---|
kCATransitionFade | 消融 |
kCATransitionPush | 压栈 |
kCATransitionReveal | 揭开幕布 |
kCATransitionMoveIn | 覆盖 |
cube | 立体翻转 |
suckEffect | 抽纸 |
oglFlip | 旋转 |
rippleEffect | 水波纹 |
pageCurl | 上翻页 |
pageUnCurl | 下翻页 |
cameraIrisHollowOpen | 相机快门开 |
cameraIrisHollowClose | 相机快门关 |