使用CAGradientLayer制作渐变折线图

之前写了一下UIBezierPath的简单使用,这次就写写UIBezierPath的具体使用吧。

如果平时我们遇到一些需要做图表的需求时,使用UIBezierPath就再适合不过了,今天我就打算使用它来绘制一个折线图。先上效果图:

logo

绘制背景

首先我们先来绘制一下背景,背景比较简单,一个背景色上边加上五条细细的线就可以了。
首先我们先用UIBezierPath来画一条直线,然后把它给到CAShapeLayer,最后把CAShapeLayer添加到当前view的sublayer中就可以了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
for(int i = 0 ; i < 5 ; i++)
{
UIBezierPath *bgPath = [UIBezierPath bezierPath];
[bgPath moveToPoint:CGPointMake(30, HEIGHT/2-100+i*30)];
[bgPath addLineToPoint:CGPointMake(WIDTH-30, HEIGHT/2-100+i*30)];
CAShapeLayer *bgPathLayer = [CAShapeLayer layer];
bgPathLayer.path = bgPath.CGPath;
bgPathLayer.lineWidth = 1;
bgPathLayer.fillColor = [UIColor clearColor].CGColor;
bgPathLayer.strokeColor = [UIColor colorWithRed:70/255.0 green:94/255.0 blue:116/255.0 alpha:0.3].CGColor;
bgPathLayer.frame = CGRectMake(0, 0, WIDTH, HEIGHT);
[self.layer addSublayer:bgPathLayer];
}

实现了上边的代码之后就会看到这样的:

logo

绘制曲线

接下来我们需要来绘制折线图的主要部分。。。折线。我之前绘制背景的时候使用了5根线所以在这边我使用随机函数arc4random()随机生成每个点的位置。所以可能生成的折线图会与最开始的效果图有一点不同。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
UIBezierPath *linePath = [UIBezierPath bezierPath];
NSInteger i = arc4random()%5;
[linePath moveToPoint:CGPointMake(30, HEIGHT/2-100+i*30)];
for(int j = 1 ; j < 30 ; j++)
{
i = arc4random()%5;
[linePath addLineToPoint:CGPointMake(30 + (WIDTH-60)*j/30, HEIGHT/2-100+i*30)];
}
CAShapeLayer *linePathLayer = [CAShapeLayer layer];
linePathLayer.path = linePath.CGPath;
linePathLayer.lineWidth = 3;
linePathLayer.fillColor = [UIColor clearColor].CGColor;
linePathLayer.strokeColor = [UIColor whiteColor].CGColor;
linePathLayer.lineCap = kCALineCapRound;
linePathLayer.frame = CGRectMake(0, 0, WIDTH, HEIGHT);
[self.layer addSublayer:linePathLayer];
logo

到这里我们折线图的部分基本就已经完成了,接下来我们要实现他的渐变色和动画的功能。

绘制渐变

CAGradientLayer

两种颜色

绘制渐变色我们需要使用到CAGradientLayer,他是用来生成两种或更多颜色平滑渐变的。

我们先简单使用CAGradientLayer来绘制一个对角线渐变的颜色。首先我们要赋予colors属性。这个数组接受的是CGColorRef类型的值,所以我们需要通过bridge转换他。

CAGradientLayer也有startPointendPoint属性,这两个属性决定了渐变的方向。其中代表左上角的坐标为{0,0},代表右下角的坐标为{1,1}。

运行这样一段代码:

1
2
3
4
5
6
7
8
9
10
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = CGRectMake(0, 0, WIDTH, HEIGHT);
[gradientLayer setColors:@[(__bridge id)[UIColor blueColor].CGColor,
(__bridge id)[UIColor redColor].CGColor
]];
[gradientLayer setStartPoint:CGPointMake(0, 0)];
[gradientLayer setEndPoint:CGPointMake(1, 0)];
[self.layer addSublayer:gradientLayer];

我们就会看到一个从左到右的蓝色渐变为红色的样式。

logo

多种颜色

当然了,我们也可以给colors添加更多的颜色,然后使用locations属性来调整空间。同样的也是以0.0代表开始、1.0代表结束。

locations数组不是一定要设置的,但是如果你设置了他,就一定要和colors的大小保持一致,否则会出现一个空白的渐变。

像这样一段代码,我在之前的基础上多加了一个绿色,并且通过locations将他们设置成了三等分。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = CGRectMake(0, 0, WIDTH, HEIGHT);
[gradientLayer setColors:@[(__bridge id)[UIColor blueColor].CGColor,
(__bridge id)[UIColor redColor].CGColor,
(__bridge id)[UIColor greenColor].CGColor
]];
[gradientLayer setLocations:@[@0.0,
@0.5,
@1.0
]];
[gradientLayer setStartPoint:CGPointMake(0, 0)];
[gradientLayer setEndPoint:CGPointMake(1, 0)];
[self.layer addSublayer:gradientLayer];
logo

如果想让渐变看起来自然一些,可以使用一些相近的颜色。比如黄色、橙色、红色。

logo

绘制蒙层

渐变也有了,折线图也有了,接下来只要把渐变的颜色设置到折线图上就可以了。我们可以使用setMask来设置一个遮罩层。

1
2
3
4
5
6
CALayer *gradientSuperLayer = [CALayer layer];
[gradientSuperLayer addSublayer:gradientLayer];
[gradientSuperLayer setMask:linePathLayer];
[self.layer addSublayer:gradientSuperLayer];

这样一来,渐变的折线图就做出来了。

logo

动画的实现

样式已经好了,接下来我们只要使用CABasicAnimation来设置一个简单的动画就可以实现功能了。

1
2
3
4
5
6
7
CABasicAnimation *drawAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
drawAnimation.duration = 2 ; //动画时间
drawAnimation.fromValue = @0;
drawAnimation.toValue= @1;
drawAnimation.fillMode = kCAFillModeForwards;
drawAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; //动画播放的方式
[layer addAnimation:drawAnimation forKey:@"draw"];
logo

以上就是渐变色折线图的简单实现方式,仅作为个人学习笔记,如果有什么地方写的不对还请大神们批评指教。