ios Core Animation层面的动画
1.Core Animation层面的动画
** CALayer 层 (显示的基础)**
UIView 核心显示功能就是依靠CALayer实现
UIView 和 CALayer 的关系
1.UIView显示能力是依赖底层的CALayer实现的,每一个UIView都包换一个CALayer对对象,修改CALayer,会影响表现出来的UIView的外观
** 2.**UIView 与 CALayer最大的不同在于,layer是不能够响应用户事件,UIView可以响应用户事件(就是不可以点击或拖拽啊什么的。。。。。)
如何获取UIView底层的那个CALayer对象
通过 .layer 属性获取
可以使用CALayer做哪些操作?
**常用属性 **
borderColor 边框颜色
borderWidth 边框宽度
cornerRadius 圆角半径
shadowOpacity 阴影透明度
shadowColor 阴影颜色
shadowRadius 阴影半径
shadowOffset 阴影偏移量
masksToBounds 是否按layer遮罩
与尺寸和位置相关的三个重要属性
bounds 大小 position 位置
anchorPosition 锚点 自身的参考点
创建新的Layer 使用 layer
图片 CALayer
给contents属性赋值: 添加图片
文字层 CATextLayer
图形层 CAShapeLayer
CALayer的很多属性都有隐式动画,在修改该属性时,会自动出现动画效果,可以通过查看头文件中,属性上面出现 animatable 这样的说明时,意味可以有隐式动画
CAAnimation动画
CA的动画,只能施加在CALayer上
CA动画与UIView动画最大的一个区别:
CA动画是假的,视图看着好像位置改变了,但其实没有变
UIView动画中,由于明确的设定了动画结束时视图的状态,所以视图的数据会随着动画的结束而真的改变
CAAnimation 的子类 之一
CABasicAnimation 基础动画
CAAnimation 的子类 之二
CAAnimationGroup 动画组
CAAnimation 的子类 之三
CAKeyFrameAnimation 关键帧动画
CALayer 层 :
-
(void)viewDidLoad {
[super viewDidLoad];
//获取 view 中的 layer 对象
CALayer *layer = self.redView.layer;
//背景颜色
layer.backgroundColor = [UIColor greenColor].CGColor;
//设置边框宽度
layer.borderWidth = 4;
//设置边框颜色
layer.borderColor = [UIColor redColor].CGColor;
//设置圆角的 半径
// layer.cornerRadius = self.redView.bounds.size.width * 0.5;
//设置阴影 一定要先设置 阴影为不透明 默认是透明 0
layer.shadowOpacity = 1;
//设置阴影颜色
layer.shadowColor = [UIColor blackColor].CGColor;
//设置阴影的圆角
layer.shadowRadius = 10;
//设置阴影的 便宜量
layer.shadowOffset = CGSizeMake(20, 20);//设置imageView的layer
CALayer *imageViewLayer = self.imageView.layer;
imageViewLayer.cornerRadius = self.imageView.bounds.size.height * 0.5;
imageViewLayer.borderWidth = 5;
imageViewLayer.borderColor = [UIColor lightGrayColor].CGColor;
//要按照层的边缘进行遮罩
imageViewLayer.masksToBounds = YES;//CALyer具有容器的特性 可以相互嵌套
//创建CALayer对象
CALayer *myLayer = [CALayer layer];
myLayer.backgroundColor = [UIColor blueColor].CGColor;
// myLayer.frame = CGRectMake(0, 0, 100, 100);//设置大小
myLayer.bounds = CGRectMake(0, 0, 100, 100);
//设置位置 当前layer 参考点(中心点) 在父layer坐标系中 的位置 默认是 0 0 点
// myLayer.position = CGPointMake(50, 50);
//设置当前 layer 参考点的位置 (锚点 默认 0.5 0.5)
// myLayer.anchorPoint = CGPointZero;
//设置 层的 旋转 (变形 是锚点操作的)
myLayer.transform = CATransform3DMakeRotation(M_PI_4, 0, 0, 1);//将自己创建的layer 添加到 self.redView的layer中
[self.redView.layer addSublayer:myLayer];
}
————————————————————————————————————
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
// [self position];
// [self transform];
// [self groupAnimation];
[self keyFrameAnimation];
}
-(void)position {
CABasicAnimation *basicAnim = [CABasicAnimation animation];
//位移position 缩放scale 旋转 rotation
//使用KVC的方式为对象赋值,说明要改的属性名是什么
basicAnim.keyPath = @"position";
basicAnim.fromValue = [NSValue valueWithCGPoint:CGPointMake(50, 50)];
//toValue 是 到 50 300的位置上
basicAnim.toValue = [NSValue valueWithCGPoint:CGPointMake(50, 300)];
//byValue 在自身基础上 移动 50 300
// basicAnim.byValue = [NSValue valueWithCGPoint:CGPointMake(50, 300)];
//动画结束时 不把动画 从视图上 移除 如果需要固定动画结束时视图的位置 必须 再配合 fillMode 该属性一起使用
basicAnim.removedOnCompletion = NO;
/*
kCAFillModeForwards 当动画结束后,layer会一致保持着动画最后的状态
kCAFillModeBackwards 在动画开始前,只需要将动画加入一个Layer,layer便立即进入动画的初始状态并等待运行动画
kCAFillModeBoth 上面两种效果叠加在一起
kCAFillModeRemoved (默认) 当动画开始前和动画结束后,动画对layer都没有影响,动画结束后,layer会恢复到之前的状态
*/
basicAnim.fillMode = kCAFillModeBoth;
//设置动画 开始前等待时间
basicAnim.beginTime = CACurrentMediaTime() + 3;
//设置动画的 相关属性
//动画持续时间
basicAnim.duration = 2;
//动画重复次数 一直重复只是给以非常大的值
// basicAnim.repeatCount = MAXFLOAT;
basicAnim.repeatCount = 1;
//运行动画 注意:CA动画只能使用 CALayer对象运行
[self.imageView.layer addAnimation:basicAnim forKey:nil];
}
-(void)transform {
CABasicAnimation *transformAnim = [CABasicAnimation animation];
// transformAnim.keyPath = @"transform";
// transformAnim.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.1, 1.2, 1)];
//动画只能执行 最后设置的 keyPath ,如果需要同时执行只能依赖 CAAnimation 的另外一个子类 CAAnimationGrop
transformAnim.keyPath = @"transform.scale";
transformAnim.toValue = @1.2;
transformAnim.keyPath = @"transform.rotation";
transformAnim.toValue = @(M_PI * 2);
transformAnim.duration = 1;
transformAnim.repeatCount = MAXFLOAT;
[self.imageView.layer addAnimation:transformAnim forKey:nil];
}
-(void)groupAnimation {
CABasicAnimation *positionAnim = [CABasicAnimation animationWithKeyPath:@"position.y"];
positionAnim.toValue = @(self.imageView.center.y + 200);
CABasicAnimation *transformAnim = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
transformAnim.toValue = @(M_PI);
CAAnimationGroup *group = [CAAnimationGroup animation];
group.animations = @[positionAnim, transformAnim];
group.duration = 3;
group.removedOnCompletion = NO;
group.fillMode = kCAFillModeForwards;
[self.imageView.layer addAnimation:group forKey:nil];
}
-(void)keyFrameAnimation {
CAKeyframeAnimation *keyFrameAnim = [CAKeyframeAnimation animation];
keyFrameAnim.keyPath = @"position";
// //设置中间行进的路线的关键值
// keyFrameAnim.values = @[
// [NSValue valueWithCGPoint:CGPointMake(50, 50)],
// [NSValue valueWithCGPoint:CGPointMake(200, 200)],
// [NSValue valueWithCGPoint:CGPointMake(60, 300)],
// [NSValue valueWithCGPoint:CGPointMake(150, 80)]];
keyFrameAnim.path = [UIBezierPath bezierPathWithRect:CGRectMake(80, 80, 200, 300)].CGPath;
keyFrameAnim.duration = 3;
keyFrameAnim.removedOnCompletion = NO;
keyFrameAnim.fillMode = kCAFillModeForwards;
[self.imageView.layer addAnimation:keyFrameAnim forKey:nil];
}