iOS Core Animation
一、Core Animation
类简介
Core Animation
是 iOS 和 OS X 平台上负责图形渲染与动画的基础框架。Core Animation
可以作用于动画视图或者其他可视元素,可以完成动画所需的大部分绘帧工作。Core Animation
系统已经进行了封装,所以在使用的时候你只需要配置少量的动画参数(如开始点的位置和结束点的位置)即可使用 Core Animation
的多种动画效果。Core Animation
将大部分实际的绘图任务交给了图形硬件(GPU)来处理,图形硬件会加速图形渲染的速度。这种自动化的图形加速技术让动画拥有更高的帧率并且显示效果更加平滑,不会加重CPU的负担而影响程序的运行速度。
Core Animation
的动画执行过程都是在后台操作的,不会阻塞主线程。
要注意的是,Core Animation
是直接作用在 CALayer
上的,并非 UIView
。
黑线代表继承,黑色文字代表类名,白色文字代表属性。其中 CAMediaTiming
是一个协议(protocol)。
CAAnimation
是所有动画类的父类,但是它不能直接使用,应该使用它的子类
CAPropertyAnimation
也是不能直接使用的,也要使用它的子类
能用的动画类只剩下4个:CABasicAnimation
、CAKeyframeAnimation``、
CATransition、
CAAnimationGroup`。
动画的各个属性及作用
1、fromValue
动画的开始值(Any
类型, 根据动画不同可以是CGPoint
、NSNumber
等)
2、toValue
动画的结束值,和 fromValue
类似
3、beginTime
动画的开始时间
4、duration
动画的持续时间
5、repeatCount
动画的重复次数
6、fillMode
动画的运行场景
7、isRemovedOnCompletion
完成后是否删除动画
8、autoreverses
执行的动画按照原动画返回执行
9、path
关键帧动画中的执行路径
10、values
关键帧动画中的关键点数组
11、animations
组动画中的动画数组
12、delegate
动画代理, 封装了动画的执行和结束方法
13、timingFunction
控制动画的显示节奏,系统提供五种值选择,分别是
-
kCAMediaTimingFunctionDefault
默认,中间快 -
kCAMediaTimingFunctionLinear
线性动画 -
kCAMediaTimingFunctionEaseIn
先慢后快 慢进快出 -
kCAMediaTimingFunctionEaseOut
先块后慢快进慢出 -
kCAMediaTimingFunctionEaseInEaseOut
先慢后快再慢
14、type
过渡动画的动画类型,系统提供了多种过渡动画,分别是
-
fade
淡出 默认 -
moveIn
覆盖原图 -
push
推出 -
fade
淡出 默认 -
reveal
底部显示出来 -
cube
立方旋转 -
suck
吸走 -
oglFlip
水平翻转 沿y轴 -
ripple
滴水效果 -
curl
卷曲翻页 向上翻页 -
unCurl
卷曲翻页返回 向下翻页 -
caOpen
相机开启 -
caClose
相机关闭
15、subtype
过渡动画的动画方向,系统提供了四种,分别是
-
fromLeft
从左侧 -
fromRight
从右侧 -
fromTop
有上面 -
fromBottom
从下面
二、基础动画CABasicAnimation
基础动画主要提供了对于 CALayer
对象中的可变属性进行简单动画的操作。比如:位移、旋转、缩放、透明度、背景色等。
基础动画根据 keyPath
来区分不同的动画,系统提供了多个类型,如:transform.scale
比例转换、transform.scale.x
、transform.scale.y
、 transform.rotation
旋转 、transform.rotation.x
绕x轴旋转、transform.rotation.y
绕y轴旋转、transform.rotation.z
绕z轴旋转、opacity
透明度、margin
、backgroundColor
背景色、cornerRadius
圆角、borderWidth
边框宽、bounds
、contents
、contentsRect
、cornerRadius
、frame
、hidden
、mask
、masksToBounds
、shadowColor
阴影色、shadowOffset
、shadowOpacity
、shadowOpacity
,在使用时候, 需要根据具体的需求选择合适的。
//
// ViewController.m
// DJTestTwo
//
// Created by admin on 2021/11/10.
//
#import "ViewController.h"
@interface ViewController ()
@property(nonatomic,strong)UIView *viewA;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:self.viewA];
[self backgroundColorAnimation];
}
//位移动画
- (void)positionAnimaton{
CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"position"];
animation.toValue = [NSValue valueWithCGPoint:CGPointMake(300, 100)];//动画要去的点
animation.duration = 2.0;//时间
[self.viewA.layer addAnimation:animation forKey:@"positionAnimaton"];//添加动画自定义的标识
}
//旋转动画
- (void)rotateAnimation{
CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
animation.toValue = [NSNumber numberWithDouble:M_PI];
animation.duration = 2.0;//时间
animation.repeatCount = 1e100;//无限大重复次数
[self.viewA.layer addAnimation:animation forKey:@"rotateAnimation"];
}
//缩放动画
- (void)scaleAnimation{
CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
animation.toValue = [NSNumber numberWithInt:2];
animation.duration = 2.0;
animation.repeatCount = 1e100;
[self.viewA.layer addAnimation:animation forKey:@"scaleAnimation"];
}
//透明度动画
- (void)opacityAnimation{
CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
animation.fromValue = [NSNumber numberWithInt:1];
animation.toValue = [NSNumber numberWithInt:0];
animation.duration = 2.0;
animation.repeatCount = 1e100;
[self.viewA.layer addAnimation:animation forKey:@"opacityAnimation"];
}
//背景色动画
- (void)backgroundColorAnimation{
CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
animation.toValue = (id)[UIColor greenColor].CGColor;
animation.duration = 2.0;
animation.repeatCount = 1e100;
[self.viewA.layer addAnimation:animation forKey:@"backgroundColorAnimation"];
}
-(UIView *)viewA{
if (!_viewA) {
_viewA = [[UIView alloc]initWithFrame:CGRectMake(10, 70, 100, 100)];
_viewA.backgroundColor = [UIColor yellowColor];
}
return _viewA;
}
@end
三、关键帧动画 CAKeyframeAnimation
CAKeyframeAnimation
和 CABasicAnimation
都属于 CAPropertyAnimatin
的子类。不同的是 CABasicAnimation
只能从一个数值(fromValue
)变换成另一个数值(toValue
),而 CAKeyframeAnimation
则会使用一个数组(values
) 保存一组关键帧,也可以给定一个路径(path
)制作动画。
CAKeyframeAnimation
主要有 三个 重要属性:
-
values
:存放关键帧(keyframe
)的数组,动画对象会在指定的时间(duration
)内,依次显示values
数组中的每一个关键帧。 -
path
:可以设置一个CGPathRef
或CGMutablePathRef
,让层跟着路径移动。path
只对CALayer
的anchorPoint
和position
起作用,如果设置了path
,那么values
将被忽略。 -
keyTimes
:可以为对应的关键帧指定对应的时间点,其取值范围为0到1.0,keyTimes
中的每一个时间值都对应values
中的每一帧。当keyTimes
没有设置的时候,各个关键帧的时间是根据duration
平分的。
//
// ViewController.m
// DJTestTwo
//
// Created by admin on 2021/11/10.
//
#import "ViewController.h"
@interface ViewController ()
@property(nonatomic,strong)UIView *viewA;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:self.viewA];
[self shakeAnimation];
}
//关键帧动画
- (void)keyFrameAnimation{
CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
animation.keyPath = @"position";
NSValue *value1 = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(200, 100)];
NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(200, 200)];
NSValue *value4 = [NSValue valueWithCGPoint:CGPointMake(100, 200)];
NSValue *value5 = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
animation.values = @[value1,value2,value3,value4,value5];
animation.repeatCount = MAXFLOAT;
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
animation.duration = 4.0f;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[self.viewA.layer addAnimation:animation forKey:@"keyFrameAnimation"];
}
//路径动画
- (void)pathAnimation{
CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
animation.keyPath = @"position";
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddEllipseInRect(path, NULL, CGRectMake(150, 100, 100, 100));
animation.path = path;
CGPathRelease(path);
animation.repeatCount = MAXFLOAT;
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
animation.duration = 4.0f;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[self.viewA.layer addAnimation:animation forKey:@"pathAnimation"];
}
//抖动动画
- (void)shakeAnimation{
CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
animation.keyPath = @"transform.rotation";
NSValue *value1 = [NSNumber numberWithDouble:M_PI/180*8];
NSValue *value2 = [NSNumber numberWithDouble:-M_PI/180*8];
animation.values = @[value1,value2];
animation.repeatCount = MAXFLOAT;
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
animation.duration = 1.0f;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[self.viewA.layer addAnimation:animation forKey:@"shakeAnimation"];
}
-(UIView *)viewA{
if (!_viewA) {
_viewA = [[UIView alloc]initWithFrame:CGRectMake(10, 70, 100, 100)];
_viewA.backgroundColor = [UIColor yellowColor];
}
return _viewA;
}
@end
四、组动画 CAAnimationGroup
CAAnimationGroup
是 CAAnimation
的子类,可以保存一组动画对象,可以保存基础动画、关键帧动画等,数组中所有动画对象可以同时并发运行,也可以通过实践设置为串行连续动画。
//
// ViewController.m
// DJTestTwo
//
// Created by admin on 2021/11/10.
//
#import "ViewController.h"
@interface ViewController ()
@property(nonatomic,strong)UIView *viewA;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:self.viewA];
[self groupAnimation];
}
- (void)groupAnimation{
CAAnimationGroup *group = [CAAnimationGroup animation];
CABasicAnimation *anim = [CABasicAnimation animation];
anim.keyPath = @"position";
anim.toValue = [NSValue valueWithCGPoint:CGPointMake(arc4random_uniform(200), arc4random_uniform(500))];
// 缩放
CABasicAnimation *anim1 = [CABasicAnimation animation];
anim1.keyPath = @"transform.scale";
// 0 ~ 1
static CGFloat scale = 0.1;
if (scale < 1) {
scale = 1.5;
}else{
scale = 0.2;
}
anim1.toValue = @(scale);
// 旋转
CABasicAnimation *anim2 = [CABasicAnimation animation];
anim2.keyPath = @"transform.rotation";
anim2.toValue = @(arc4random_uniform(360) / 180.0 * M_PI);
group.animations = @[anim,anim1,anim2];
group.duration = 0.5;
// 取消反弹
// 告诉在动画结束的时候不要移除
group.removedOnCompletion = NO;
// 始终保持最新的效果
group.fillMode = kCAFillModeForwards;
[self.viewA.layer addAnimation:group forKey:nil];
}
-(UIView *)viewA{
if (!_viewA) {
_viewA = [[UIView alloc]initWithFrame:CGRectMake(10, 70, 100, 100)];
_viewA.backgroundColor = [UIColor yellowColor];
}
return _viewA;
}
@end
五、过渡动画 CATransition
CATransition
是 CAAnimation
的子类,用于做过渡动画或者转场动画,能够为层提供移出屏幕和移入屏幕的动画效果。
过渡动画通过 type
设置不同的动画效果,CATransition
有多种过渡效果,但其实 Apple 官方的SDK只提供了四种:
-
fade
淡出 默认 -
moveIn
覆盖原图 -
push
推出 -
reveal
底部显示出来