前言,编写了一些有关 CALayer 的应用。下载进度条控件、UIImageView 淡入淡出切换图片效果、复杂遮罩效果、音量条效果。
一、下载进度条控件
- 1.创建 CALayer 控件
- 2.直接修改 CALayer 的 frame 值执行隐式动画,实现进度条效果。
- 3.获取下载进度数据(本次使用计时器模拟动态数据)
- 4.将 CALayer 封装进 UIView 的子类中。
代码示例:
@property (nonatomic, strong) CALayer *progressBarLayer;
- (void)createProgressBar{
_progressBarLayer = [CALayer layer];
_progressBarLayer.frame = CGRectMake(50, 50, 200, 4);
_progressBarLayer.backgroundColor = [UIColor orangeColor].CGColor;
_progressBarLayer.cornerRadius = 2.0;
[self.view.layer addSublayer:_progressBarLayer];
[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(getProgressNum) userInfo:nil repeats:YES];
}
- (void)getProgressNum{
_progressBarLayer.frame = CGRectMake(50, 50, arc4random()%200, 4);
}
效果展示:
二、UIImageView 淡入淡出切换图片效果
- 1.操作 UIImageView 的 CALayer 修改其 bounds 值进行显式动画
- 2.修改 UIImageView 的 CALayer 中的 contents 属性实现切换图片的动画
- 3.使用 CAAnimationGroup 将 bounds 动画与 contents 动画组合起来
- 4.效果封装进 UIView 的子类中。
创建 CALayer
- (void)createImgLayer{
_imgLayer = [CALayer layer];
_imgLayer.frame = CGRectMake(50, 50, 100, 200);
[self.view.layer addSublayer:_imgLayer];
_imgLayer.contents = (__bridge id)([UIImage imageNamed:@"1"].CGImage);
[self performSelector:@selector(imgAnimation) withObject:nil afterDelay:2.0];
}
2.1 方法一:隐式动画
无法控制持续时间等等的参数。动画执行时间特别迅速,无法控制。
- (void)imgAnimation{
// 方法一:执行隐式动画
_imgLayer.contents = (__bridge id)([UIImage imageNamed:@"2"].CGImage);
}
效果展示
2.2 方法二:显式动画
通过改变基本动画参数来进行图片的转换。
- (void)imgAnimation{
// 方法二:执行显式动画
CABasicAnimation *anima = [CABasicAnimation animationWithKeyPath:@"contents"];
anima.fromValue = self.imgLayer.contents;
anima.toValue = (__bridge id)([UIImage imageNamed:@"3"].CGImage);
anima.duration = 2.0;
// 设定layer动画结束后的contents值
_imgLayer.contents = (__bridge id)([UIImage imageNamed:@"3"].CGImage);
// 让layer开始执行动画
[_imgLayer addAnimation:anima forKey:nil];
}
效果展示
2.3 方法三:显式动画
通过修改图片和 bounds,配合动画组来实现。
- (void)imgAnimation{
//方法三:执行显式动画
//基于图片的动画实现
CABasicAnimation *imgAnima = [CABasicAnimation animationWithKeyPath:@"contents"];
imgAnima.fromValue = self.imgLayer.contents;
imgAnima.toValue = (__bridge id)([UIImage imageNamed:@"3"].CGImage);
imgAnima.duration = 1;
CABasicAnimation *boundsAnima = [CABasicAnimation animationWithKeyPath:@"ounds"];
boundsAnima.fromValue = [NSValue valueWithCGRect:_imgLayer.bounds];
boundsAnima.toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, _imgLayer.bounds.size.width*0.5, _imgLayer.bounds.size.height*0.5)];
boundsAnima.duration = 1;
// 将基于图片的动画与基于bounds的动画组合起来
CAAnimationGroup *groupAnima = [CAAnimationGroup animation];
groupAnima.animations = @[imgAnima, boundsAnima];
groupAnima.duration = 0.5f;
// 设定layer动画结束后的contents值
_imgLayer.contents = (__bridge id)([UIImage imageNamed:@"3"].CGImage);
_imgLayer.bounds = CGRectMake(0, 0, _imgLayer.bounds.size.width*0.5, _imgLayer.bounds.size.height*0.5);
[_imgLayer addAnimation:groupAnima forKey:nil];
}
执行效果
三、复杂遮罩效果
- 1.遮罩原理分析
- 2.使用 png 图片作为 CALayer 中的 mask 属性的遮罩 Layer
-
3.移动 layer 的 mask 的 frame 值实现遮罩动画效果
//变量声明
@property (nonatomic, strong) CALayer *imageLayer;
@property (nonatomic, strong) CALayer *maskLayer;
@property (nonatomic, strong) UIImage *contentImage;
@property (nonatomic, strong) UIImage *maskImage;
// 处理图片
self.contentImage = [UIImage imageNamed:@"原始图片"];
self.maskImage = [UIImage imageNamed:@"maskLayerContents"];
// 生成maskLayer
self.maskLayer = [CALayer layer];
self.maskLayer.frame = CGRectMake(0, 0, 427/2.f, 427/2.f);
self.maskLayer.contents = (__bridge id)(self.maskImage.CGImage);
// 生成contentsLayer
self.imageLayer = [CALayer layer];
self.imageLayer.frame = CGRectMake(0, 0, 427/2.f, 427/2.f);
self.imageLayer.contents = (__bridge id)(self.contentImage.CGImage);
// 给contentsLayer设定mask值
self.imageLayer.mask = self.maskLayer;
// 将contentsLayer添加到layer中
[self.view.layer addSublayer:self.imageLayer];
四、音乐音量条效果
1.创建复制层
2.创建一个振动 layer
3.添加动画
- (void)viewDidLoad {
[super viewDidLoad];
//复制层
CAReplicatorLayer *repL = [CAReplicatorLayer layer];
repL.frame = self.contentV.bounds;
[self.contentV.layer addSublayer:repL];
repL.instanceCount = 5;
repL.instanceTransform = CATransform3DMakeTranslation(45, 0, 0);
//设置复制出来的子层动画的延时执行时长
repL.instanceDelay = 1;
//创建一个振动条
CALayer *layer = [CALayer layer];
layer.backgroundColor = [UIColor redColor].CGColor;
layer.bounds = CGRectMake(0, 0, 30, 100);
layer.anchorPoint = CGPointMake(0, 1);
layer.position = CGPointMake(0, self.contentV.bounds.size.height);
[repL addSublayer:layer];
//添加动画
CABasicAnimation *anim = [CABasicAnimation animation];
anim.keyPath = @"transform.scale.y";
anim.toValue = @0;
anim.repeatCount = MAXFLOAT;
anim.duration = 1;
anim.autoreverses = YES;
[layer addAnimation:anim forKey:nil];
}