CABasicAnimation可以设定keyPath的起点,终点的值,动画会沿着设定点进行移动,CABasicAnimation可以看成是只有两个关键点的特殊的CAKeyFrameAnimation。
先看一个简单的移动动画的例子:
- (void)position {
/* 移动 */
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
animation.duration = 2.5; // 持续时间
animation.repeatCount = 1; // 重复次数
// animation.beginTime = CACurrentMediaTime() + 1; // 1秒后执行
// animation.autoreverses = YES; // 结束后执行逆动画
// // 动画终了后不返回初始状态---下面2句代码都要有
// animation.removedOnCompletion = NO;
// animation.fillMode = kCAFillModeForwards;
//
// 动画先加速后减速
animation.timingFunction =
[CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseInEaseOut];
// 起始帧和终了帧的设定
animation.fromValue = [NSValue valueWithCGPoint:self.imageView1.layer.position]; // 起始帧
animation.toValue = [NSValue valueWithCGPoint:CGPointMake(50, 350)]; // 终了帧
//为Layer添加设置完成的动画,可以给Key指定任意名字。
[self.imageView1.layer addAnimation:animation forKey:@"move-layer"];
}
- 常见属性和使用步骤
4.1 使用步骤
通常分成三部完成:
1,创建核心动画对象;
2,设置动画属性;
3,添加到要作用的layer上。
4.2 常用属性
-
duration
:持续时间,默认值是0.25秒 -
repeatCount
:重复次数,无线循环可以设置HUGE_VALF或者CGFLOAT_MAX -
repeatDuration
:重复时间 -
removeOnCompletion
: 默认为YES,代表动画执行完毕后就从图层上移除,图形会恢复到执行动画之前的状态。如果想要图层保持显示动画执行后的状态,那就设置为NO,同时设置fillMode为kCAFillModeForwards -
fillMode
:决定当前对象在非active时间段的行为 -
beginTime
:可以用来设置动画延时执行,若想延迟2s,就设置为CACurrentMediaTIme() + 2 -
CACurrentMediaTIme()
:图层的当前时间 -
timingFunction
:速度控制函数,控制动画运行节奏 -
delegate
:动画代理
4.3 animationWithKeyPath中,常用的keyPath见下表:
属性名称 | 类型 | 作用 |
---|---|---|
transform.rotation.x | CGFloat或float | 绕X轴坐标旋转 角度 |
transform.rotation.y | CGFloat或float | 绕Y轴坐标旋转 角度 |
transform.rotation.z | CGFloat或float | 绕Z轴坐标旋转 角度 |
transform.rotation | CGFloat或float | 作用与transform.tation.z一样 |
------ | ------ | ------ |
transform.scale | CGFloat | 整个layer的比例 |
transform.scale.x | CGFloat | x轴坐标比例变化 |
transform.scale.y | CGFloat | y轴坐标比例变化 |
transform.scale.z | CGFloat | z轴坐标比例变化 |
------ | ------ | ------ |
transform.translation | CGMutablePathRef | 整个layer的xyz轴都进行移动 |
transform.translation.x | CGMutablePathRef | 横向移动 |
transform.translation.y | CGMutablePathRef | 纵向移动 |
transform.translation.z | CGMutablePathRef | 纵深移动 |
------ | ------ | ------ |
opacity | CGFloat | 透明度,闪烁等动画用 。范围是0~1 |
backgroundColor | CGColor | 背景颜色 |
cornerRadius | CGFloat | 圆角 |
contents | id | 比如imageView可以改变图片 |
shadowRadius | CGFloat | 阴影的半径 |
shadowOpacity | CGFloat | 阴影的透明度,范围是0~1 |
shadowOffset | CGSize | 阴影的偏移量 |
shadowColor | CGColor | 阴影颜色 |
bounds | CGRect | 改变尺寸大小,跟放大缩小效果一样 |
borderWidth | CGFloat | 边框宽度 |
frame | CGRect | 坐标 |
position | CGPoint | 移动的动画 |
masksToBounds | ----- | 是否裁剪,暂未使用过这个属性 |
hidden | ----- | 是否隐藏 , 暂未使用过这个属性 |
mask | ----- | 暂未使用过这个属性 |
margin | ----- | 暂未使用过这个属性 |
zPosition | ----- | 暂未使用过这个属性 |
4.4 动画填充模式
kCAFillModeForwards:当动画结束后,layer会一直保持着动画最后的状态
kCAFillModeBackwards:在动画开始前,只需要将动画加入了一个layer,layer便立即进入动画的初始状态并等待动画开始
kCAFillModeBoth:这个其实就是上面两个合成,动画加入后,开始之前,layer便处于动画初始状态,动画结束后layer保持动画最后的状态
kCAFillModeRemoved:这个是默认值,也就是说当动画开始前和动画结束后,动画对layer都没有影响,动画结束后,layer会恢复到之前的状态
4.5 速度控制函数
-
kCAMediaTimingFunctionLinear
(线性):匀速,给你一个相对静态的感觉 -
kCAMediaTimingFunctionEaseIn
(渐进):动画缓慢进入,然后加速离开 -
kCAMediaTimingFunctionEaseOut
(渐出):动画全速进入,然后减速的到达目的地 -
kCAMediaTimingFunctionEaseInEaseOut
(渐进渐出):动画缓慢的进入,中间加速,然后减速的到达目的地。这个是默认的动画行为。
下面看几个常用例子:
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
animation.duration = 2.5; // 持续时间
animation.repeatCount = 1000; // 重复次数
// 动画先加速后减速
animation.timingFunction =
[CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionLinear];
animation.fromValue = [NSNumber numberWithFloat:0];
animation.toValue = [NSNumber numberWithFloat:M_PI *2];
//为Layer添加设置完成的动画,可以给Key指定任意名字。
[self.imageView1.layer addAnimation:animation forKey:@"rotation-layer"];
- (void)position {
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
animation.duration = 2.5; // 持续时间
animation.repeatCount = 1000; // 重复次数
// 动画先加速后减速
animation.timingFunction =
[CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionLinear];
animation.fromValue = [NSNumber numberWithFloat:1];
animation.toValue = [NSNumber numberWithFloat:2];
//为Layer添加设置完成的动画,可以给Key指定任意名字。
[self.imageView1.layer addAnimation:animation forKey:@"scale-layer"];
}
- (void)position {
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.translation.x"];
animation.duration = 2.5; // 持续时间
animation.repeatCount = 1000; // 重复次数
// 动画先加速后减速
animation.timingFunction =
[CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionLinear];
animation.fromValue = [NSNumber numberWithFloat:0];
animation.toValue = [NSNumber numberWithFloat:200];//横线移动200
//为Layer添加设置完成的动画,可以给Key指定任意名字。
[self.imageView1.layer addAnimation:animation forKey:@"translation-layer"];
}
- (void)position {
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
animation.duration = 2.5; // 持续时间
animation.repeatCount = 1000; // 重复次数
// 动画先加速后减速
animation.timingFunction =
[CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionLinear];
animation.fromValue = [NSNumber numberWithFloat:1];
animation.toValue = [NSNumber numberWithFloat:0];
//为Layer添加设置完成的动画,可以给Key指定任意名字。
[self.imageView1.layer addAnimation:animation forKey:@"translation-layer"];
}
- (void)position {
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
animation.duration = 2.5; // 持续时间
animation.repeatCount = 1000; // 重复次数
// 动画先加速后减速
animation.timingFunction =
[CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionLinear];
animation.fromValue = (id)[UIColor redColor].CGColor;
animation.toValue = (id)[UIColor greenColor].CGColor;
//为Layer添加设置完成的动画,可以给Key指定任意名字。
[self.imageView1.layer addAnimation:animation forKey:@"backgroundColor-layer"];
}
_imageView1 = [[UIImageView alloc]init];
_imageView1.backgroundColor = [UIColor grayColor];
// _imageView1.image = mImageByName(@"haha");
self.imageView1.layer.shadowColor = [UIColor redColor].CGColor;
self.imageView1.layer.shadowOffset = CGSizeMake(0, 0.6);
self.imageView1.layer.shadowOpacity = 0.5;//阴影透明度,默认0
self.imageView1.layer.shadowRadius = 20;//阴影半径,默认3
- (void)position {
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"shadowColor"];
animation.duration = 2.5; // 持续时间
animation.repeatCount = 1000; // 重复次数
// 动画先加速后减速
animation.timingFunction =
[CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionLinear];
animation.fromValue = (id)[UIColor redColor].CGColor;
animation.toValue = (id)[UIColor greenColor].CGColor;
//为Layer添加设置完成的动画,可以给Key指定任意名字。
[self.imageView1.layer addAnimation:animation forKey:@"shadowColor-layer"];
}
- (void)position {
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
animation.duration = 2.5; // 持续时间
animation.repeatCount = 1000; // 重复次数
// 动画先加速后减速
animation.timingFunction =
[CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionLinear];
animation.fromValue = [NSNumber numberWithFloat:0];
animation.toValue = [NSNumber numberWithFloat:M_PI*22];
//为Layer添加设置完成的动画,可以给Key指定任意名字。
[self.imageView1.layer addAnimation:animation forKey:@"rotation-layer"];
}
- (void)position {
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"contents"];
animation.duration = 2.5; // 持续时间
animation.repeatCount = 1000; // 重复次数
// 动画先加速后减速
animation.timingFunction =
[CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionLinear];
animation.fromValue = (id)mImageByName(@"haha").CGImage;
animation.toValue = (id)mImageByName(@"bird").CGImage;
//为Layer添加设置完成的动画,可以给Key指定任意名字。
[self.imageView1.layer addAnimation:animation forKey:@"rotation-layer"];
}
#pragma mark 动画暂停
- (void)pauseAnimation
{
// 1. 取出当前的动画的时间点,就是要暂停的时间点
CFTimeInterval pauseTime = [self.myView.layer convertTime:CACurrentMediaTime() fromLayer:nil];
// 2. 设置动画的时间偏移量,指定时间偏移量的目的是让动画定格在该时间点
[self.myView.layer setTimeOffset:pauseTime];
// 3. 将动画的运行速度设置为0,动画默认的运行速度是1.0
[self.myView.layer setSpeed:0.0];
}
#pragma mark 恢复动画
- (void)resumeAnimation
{
// 1. 将动画的时间偏移量作为暂停时的时间点
CFTimeInterval pauseTime = self.myView.layer.timeOffset;
// 2. 根据媒体时间计算出准确的启动动画时间,对之前暂停动画的时间进行修正
CFTimeInterval beginTime = CACurrentMediaTime() - pauseTime;
// 3. 要把偏移时间清零
[self.myView.layer setTimeOffset:0.0];
// 4. 设置图层的开始动画时间
[self.myView.layer setBeginTime:beginTime];
[self.myView.layer setSpeed:1.0];
}
注意:
// 对于循环播放的动画效果,一定要将removedOnCompletion设置为NO,否则无法恢复动画
[anim setRemovedOnCompletion:NO];