CAlayer的使用

一,CALayer简介
1、CALayer一般作为UIView的容器而使用 
2、CALayer是一个管理着图片载体(image-based  content)的层结构 
3、直接修改单独创建出的CALayer的属性可以触发隐式动画 
4、UIView中的CALayer动画必须显式触发才能生效 

二,用CALayer创建下载进度条
1、单独创建出CALayer 
2、直接修改CALayer的frame值执行隐式动画,实现进度条效果 
3、用定时器(NSTimer)模拟网络下载时提供的百分比数据 
4、将CALayer封装进UIView子类中定制进度条控件 

用CALayer做进度条,主要以修改其frame触发其隐式动画以达到目的,如图所示:
这里写图片描述

// 创建layer并添加layer
CALayer *layer = [CALayer layer];
layer.frame = CGRectMake(0, 0, 100, 5); [self.view.layer addSublayer:layer];
// 执⾏行隐式动画(直接触发动画效果) layer.frame = CGRectMake(0, 0, 200, 5);

最后将CALayer封装进UIView子类,实现定制进度条控件,以达到代码复用的目的

ProgressView.h文件

#import <UIKit/UIKit.h>
@interface ProgressView : UIView
@property (nonatomic, assign) CGFloat  progress;   // 进度参数(取值范围为 %0 ~ %100)
@property (nonatomic, strong) UIColor *layerColor; // 修改layer的颜色
@end

ProgressView.m文件

#import "ProgressView.h"

@interface ProgressView ()

@property (nonatomic, strong) CALayer *progressLayer;
@property (nonatomic, assign) CGFloat  currentViewWidth;

@end

@implementation ProgressView

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.progressLayer       = [CALayer layer];
        self.progressLayer.frame = CGRectMake(0, 0, 0, frame.size.height);
        self.progressLayer.backgroundColor = [UIColor redColor].CGColor;
        [self.layer addSublayer:self.progressLayer];

        // 存储当前view的宽度值
        self.currentViewWidth = frame.size.width;
    }
    return self;
}

#pragma mark - 重写setter,getter方法
@synthesize progress = _progress;
- (void)setProgress:(CGFloat)progress {
    _progress = progress;

    if (progress <= 0) {
        self.progressLayer.frame = CGRectMake(0, 0, 0, self.frame.size.height);
    } else if (progress <= 1) {
        self.progressLayer.frame = CGRectMake(0, 0,
                                              progress * self.currentViewWidth,
                                              self.frame.size.height);
    } else {
        self.progressLayer.frame = CGRectMake(0, 0, self.currentViewWidth,
                                              self.frame.size.height);
    }
}
- (CGFloat)progress {
    return _progress;
}

@synthesize layerColor = _layerColor;
- (void)setLayerColor:(UIColor *)layerColor {
    _layerColor = layerColor;
    self.progressLayer.backgroundColor = layerColor.CGColor;
}
- (UIColor *)layerColor {
    return _layerColor;
}

@end

三,用CALayer定制UIImageView淡入淡出切换图片效果

用CALayer定制UIImageView淡入淡出切换图片效果,需要有中间图片作为过度帧,如下图所示,使用核心的动画切换图片,就会达到一种淡入淡出的效果。
这里写图片描述

1、操作UIImageView的CALayer修改其bounds值进行显式动画 

 // 设定基本动画参数
CABasicAnimation *contentsAnimation = [CABasicAnimation animationWithKeyPath:@"contents"];
contentsAnimation.fromValue         =  self.imageLayer.contents;
contentsAnimation.toValue           =  (__bridge id)([UIImage imageNamed:@"结束图片"].CGImage);
contentsAnimation.duration          = 3.f;

// 设定layer动画结束后的contents值
self.imageLayer.contents         = (__bridge id)([UIImage imageNamed:@"结束图片"].CGImage);

// 让layer开始执行动画
[self.imageLayer addAnimation:contentsAnimation forKey:nil];

2、修改UIImageView的CALayer中的contents属性实现切换图片的动画 

 // 基于bounds的动画
CABasicAnimation *boundsAnimation = [CABasicAnimation animationWithKeyPath:@"bounds"];
boundsAnimation.fromValue         = [NSValue valueWithCGRect:self.imageLayer.bounds];
boundsAnimation.toValue           = [NSValue valueWithCGRect:CGRectMake(0, 0, 302/2.f, 707/2.f)];
boundsAnimation.duration          = 0.5f;

3、用CAAnimationGroup将bounds动画与contents动画组合起来

// 将基于图片的动画与基于bounds的动画组合起来
CAAnimationGroup *groupAnimation = [CAAnimationGroup animation];
groupAnimation.animations        = @[contentsAnimation, boundsAnimation];
groupAnimation.duration          = 0.5f;

// 设定layer动画结束后的contents值
self.imageLayer.contents = (__bridge id)([UIImage imageNamed:@"结束图片"].CGImage);
self.imageLayer.bounds   = CGRectMake(0, 0, 302/2.f, 707/2.f);

// 让layer开始执行动画
[self.imageLayer addAnimation:groupAnimation forKey:nil];

4、将上述效果封装进UIView的子类中生成控件 
FadeImageView.h文件

#import <UIKit/UIKit.h>

@interface FadeImageView : UIView

@property (nonatomic, strong) UIImage *image;

@end

FadeImageView.m文件

#import "FadeImageView.h"

@implementation FadeImageView

@synthesize image = _image;
- (void)setImage:(UIImage *)image {
    _image = image;

    NSLog(@"测试");
    if (self.layer.contents != nil) {
        CABasicAnimation *contentsAnimation = [CABasicAnimation animationWithKeyPath:@"contents"];
        contentsAnimation.fromValue = self.layer.contents;
        contentsAnimation.toValue   = (__bridge id)(image.CGImage);
        contentsAnimation.duration  = 1.f;

        self.layer.contents = (__bridge id)(image.CGImage);
    }
}
- (UIImage *)image {
    return _image;
}
@end

四,用CALayer实现复杂遮罩效果
1、遮罩原理的分析
遮罩的原理如图所示,第一张图为原始图片,第二张图为具有alpha通道的图片,黑色可以穿透,边缘白色无法穿透,叠加到原始图片上时候,就会有第三张图的效果,以此达到遮罩的目的。

这里写图片描述

2、用png图片作为CALayer中mask属性的遮罩Layer 

// 处理图片
    self.contentImage = [UIImage imageNamed:@"原始图片"];
    self.maskImage    = [UIImage imageNamed:@"遮罩图片"];

    // 生成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];

3、移动该CALayer的mask的frame值实现遮罩动画效果 

self.maskLayer.frame = CGRectMake(50, 50, 200, 200);

简单修改遮罩的frame值可以实现许多动画效果。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值