CoreAnimation之CAGradientLayer

CAGradientLayer可以绘制颜色渐变的图层,先来看一些它的属性:

colors 图层上所有的颜色数组
locations 颜色数组中各种颜色所占的比例
startPoint 图层颜色变化开始点,图层左上角(0,0),右下角(1,1),中间点为(0.5,0.5)
endPoint 图层颜色变化结束点
type 绘制类型,目前只有默认的轴向类型kCAGradientLayerAxial

CAGradientLayer *gradientLayer = [CAGradientLayer layer];
    gradientLayer.bounds = CGRectMake(0, 0, 200, 200);
    gradientLayer.position = CGPointMake([UIScreen mainScreen].bounds.size.width/2, 550);
    gradientLayer.backgroundColor = [UIColor lightGrayColor].CGColor;
    gradientLayer.colors = @[(__bridge id)[UIColor redColor].CGColor,
                             (__bridge id)[UIColor greenColor].CGColor,
                             (__bridge id)[UIColor yellowColor].CGColor,
                             (__bridge id)[UIColor blueColor].CGColor];
    gradientLayer.locations = @[@0.25,@0.5,@0.75,@1];
    gradientLayer.startPoint = CGPointMake(0.5, 0);
    gradientLayer.endPoint = CGPointMake(0.5, 1);
    [self.view.layer addSublayer:gradientLayer];
gradientLayer1.png
    //添加一个动画显示文字的的图层
    //1.添加文字
    UILabel *textLabel = [[UILabel alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width/2-100, 450, 200, 200)];
    textLabel.textAlignment = NSTextAlignmentCenter;
    textLabel.text = @"MacPen";
    textLabel.backgroundColor = [UIColor clearColor];
    textLabel.textColor = [UIColor blackColor];
    textLabel.font = [UIFont systemFontOfSize:30];
    [self.view addSubview:textLabel];
    //2.添加一个颜色渐变的图层
    CAGradientLayer *gradientLayer = [CAGradientLayer layer];
    gradientLayer.bounds = textLabel.bounds;
    gradientLayer.position = textLabel.center;
    gradientLayer.colors = @[(__bridge id)[UIColor blackColor].CGColor,
                             (__bridge id)[UIColor whiteColor].CGColor,
                             (__bridge id)[UIColor blackColor].CGColor];
    gradientLayer.locations = @[@0.3,@0.5,@0.7];
    gradientLayer.startPoint = CGPointMake(0, 0.5);
    gradientLayer.endPoint = CGPointMake(1, 0.5);
    [self.view.layer addSublayer:gradientLayer];
    //将文字层设置成渐变层的遮罩mask,mask的意思就是按透明度裁剪,透明部分裁剪,非透明部分保留,也就是文字部分被保留,渐变层去填充保留的文字部分的颜色
    gradientLayer.mask = textLabel.layer;
    //lable.layer被设置为gradientLayer的mask,也就是label从原来的父视图上移除,将lable.layer的父图层就被设置为gradientLayer,那么label的frame就要以gradientLayer作为参考坐标系重新设置
    textLabel.frame = gradientLayer.bounds;
    //3.给渐变图层的颜色加一个动画
    CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"locations"];
    basicAnimation.fromValue = @[@0,@0,@0.25];
    basicAnimation.toValue = @[@0.75,@1,@1];
    basicAnimation.repeatCount = HUGE_VALF;
    basicAnimation.duration = 1.5;
    [gradientLayer addAnimation:basicAnimation forKey:nil];

这里先对gradientLayer.locations进行一个说明,gradientLayer.locations = @[@0.3,@0.5,@0.7];在图层上的表现占比如下图

gradientLayer2.png

实现的文字效果如下


gradientLayer.gif

然后我们使用CAGradientLayer和CAShapeLayer制作一个颜色渐变的进度条,先看一下效果


gradientProgressLayer.gif

这个效果主要分两部分,一个是中间的文字以及文字内容和颜色的动画,另一个就是进度条及其动画。
先看第一部分文字设置及动画,这里使用CATextLayer完成:

    //添加一个文字图层
    self.textLayer = [CATextLayer layer];
    self.textLayer.bounds = CGRectMake(0, 0, 100, 60);
    self.textLayer.position = CGPointMake(self.view.bounds.size.width/2, 550);
    self.textLayer.foregroundColor = [UIColor redColor].CGColor;
    self.textLayer.fontSize = 30;
    self.textLayer.alignmentMode = kCAAlignmentCenter;
    self.textLayer.string = @"0%";
    [self.view.layer addSublayer:self.textLayer];
    //文字颜色动画使用关键帧动画
    CAKeyframeAnimation *textAnimation = [CAKeyframeAnimation animationWithKeyPath:@"foregroundColor"];
    textAnimation.values = @[(id)[UIColor greenColor].CGColor,
                             (id)[UIColor yellowColor].CGColor,
                             (id)[UIColor redColor].CGColor];
    textAnimation.repeatCount = 1;
    textAnimation.duration = 1.7;
    [self.textLayer addAnimation:textAnimation forKey:nil];

    //使用CADisplayLink刷新文字图层中的文字
    [self startDisplayLink];
    [self performSelector:@selector(stopDisplayLink) withObject:nil afterDelay:1.7];
- (void)startDisplayLink{
    self.displayLink = [CADisplayLink displayLinkWithTarget:self
                                                   selector:@selector(handleDisplayLink:)];
    self.displayLink.preferredFramesPerSecond = 60;
    [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop]
                           forMode:NSDefaultRunLoopMode];
}
- (void)handleDisplayLink:(CADisplayLink *)displayLink{
    if (self.progress < 100) {
        self.progress += 1;
        self.textLayer.string = [NSString stringWithFormat:@"%d%%",self.progress];
    }
}
- (void)stopDisplayLink{
    [self.displayLink invalidate];
    self.displayLink = nil;
}

第二部分就是进度条的设置,方法就是在两个渐变的拼接图层上添加进度条的遮罩层,那么显示进度条的地方就会显示底层的渐变色。

    //添加环形的进度条的浅色背景
    UIBezierPath *backCirclePath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 100) radius:90 startAngle:-M_PI*7/6 endAngle:M_PI/6 clockwise:YES];
    CAShapeLayer *backCircleLayer = [CAShapeLayer layer];
    backCircleLayer.frame = CGRectMake([UIScreen mainScreen].bounds.size.width/2-100, 450, 200, 200);
    backCircleLayer.fillColor = [UIColor clearColor].CGColor;
    backCircleLayer.strokeColor = [UIColor grayColor].CGColor;
    backCircleLayer.lineWidth = 5;
    backCircleLayer.path = backCirclePath.CGPath;
    backCircleLayer.lineCap = kCALineCapRound;
    backCircleLayer.opacity = 0.25;
    [self.view.layer addSublayer:backCircleLayer];
    backCircleLayer.strokeStart = 0;
    backCircleLayer.strokeEnd = 1;
    //添加环形的进度条
    UIBezierPath *circlePath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 100) radius:90 startAngle:-M_PI*7/6 endAngle:M_PI/6 clockwise:YES];
    self.circleLayer = [CAShapeLayer layer];
    self.circleLayer.frame = CGRectMake([UIScreen mainScreen].bounds.size.width/2-100, 450, 200, 200);
    self.circleLayer.fillColor = [UIColor clearColor].CGColor;
    self.circleLayer.strokeColor = [UIColor grayColor].CGColor;
    self.circleLayer.lineWidth = 5;
    self.circleLayer.lineCap = kCALineCapRound;
    self.circleLayer.path = circlePath.CGPath;
    [self.view.layer addSublayer:self.circleLayer];
    self.circleLayer.strokeStart = 0;
    self.circleLayer.strokeEnd = 1;
    //环形进度条添加动画
    CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    basicAnimation.fromValue = @[@0];
    basicAnimation.toValue = @[@1];
    basicAnimation.repeatCount = 1;
    basicAnimation.duration = 1.7;
    [self.circleLayer addAnimation:basicAnimation forKey:nil];
    //添加颜色渐变的图层
    //承载图层
    CALayer *coverLayer = [CALayer layer];
    coverLayer.frame = CGRectMake([UIScreen mainScreen].bounds.size.width/2-100, 450, 200, 200);
    //左半边渐变图层
    CAGradientLayer *gradientLayer1 = [CAGradientLayer layer];
    gradientLayer1.frame = CGRectMake(0, 0, 100, 200);
    gradientLayer1.colors = @[(__bridge id)[UIColor greenColor].CGColor,
                             (__bridge id)[UIColor yellowColor].CGColor];
    gradientLayer1.locations = @[@0.3,@0.7];
    gradientLayer1.startPoint = CGPointMake(0, 1);
    gradientLayer1.endPoint = CGPointMake(1, 0);
    [coverLayer addSublayer:gradientLayer1];
    //右半边渐变图层
    CAGradientLayer *gradientLayer2 = [CAGradientLayer layer];
    gradientLayer2.frame = CGRectMake(100, 0, 100, 200);
    gradientLayer2.colors = @[(__bridge id)[UIColor yellowColor].CGColor,
                              (__bridge id)[UIColor redColor].CGColor];
    gradientLayer2.locations = @[@0.3,@0.7];
    gradientLayer2.startPoint = CGPointMake(0, 0);
    gradientLayer2.endPoint = CGPointMake(1, 1);
    [coverLayer addSublayer:gradientLayer2];
    //将环形图层设置为渐变色图层的mask
    coverLayer.mask = self.circleLayer;
    self.circleLayer.frame = coverLayer.bounds;
    [self.view.layer addSublayer:coverLayer];

参考链接
http://blog.csdn.net/zhoutao198712/article/details/20864143

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容