图形绘制
线条绘制
单轨迹线条绘制设置线宽,动画进可以通过 KeyPath 设置为 strokeEnd 进行渲染,达到动态渲染的目的
// 绘制轨迹
UIBezierPath *bezierPath = [UIBezierPath bezierPath];
[bezierPath moveToPoint:CGPointMake(200, 200)];
[bezierPath addLineToPoint:CGPointMake(150, 100)];
// 轨迹渲染
CAShapeLayer * layer = [CAShapeLayer layer];
layer.fillColor = [UIColor redColor].CGColor;
layer.strokeColor = [UIColor redColor].CGColor;
layer.strokeStart = 0;
layer.strokeEnd = 1;
layer.zPosition = 1;
layer.lineWidth = 1;
layer.path = bezierPath.CGPath;
[self.view.layer addSublayer:layer];
// 轨迹动画
CABasicAnimation * pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
pathAnimation.duration = 1.0f;
pathAnimation.fromValue = @0.0f;
pathAnimation.toValue = @1.0f;
pathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];//添加动画样式
// 添加动画
[layer addAnimation: pathAnimation forKey:@"strokeEndAnimation"];
三角形绘制
简单绘制一个三角形,bezierPath 调用 closePath 时, 绘制的线路必须是闭合的,再调用 closePath 才能闭合,但是动画设置为 strokeEnd 却无效,需要重新设置动画组合 CAAnimationGroup 才能添加渲染动画
绘制如图图形
// 绘制三角形
UIBezierPath *bezierPath = [UIBezierPath bezierPath];
[bezierPath moveToPoint:CGPointMake(200, 200)];
[bezierPath addLineToPoint:CGPointMake(150, 100)];
[bezierPath addLineToPoint:CGPointMake(250, 100)];
[bezierPath closePath];
// 填充红色颜色
CAShapeLayer * layer = [CAShapeLayer layer];
layer.fillColor = [UIColor redColor].CGColor;
layer.strokeColor = [UIColor redColor].CGColor;
layer.strokeStart = 0;
layer.strokeEnd = 1;
layer.zPosition = 1;
layer.lineWidth = 1;
layer.path = bezierPath.CGPath;
[self.view.layer addSublayer:layer];
// 添加动画
[layer addAnimation:[self pathAnimation] forKey:@"strokeEndAnimation"];
折线图绘制
通过折线图绘制,可以满足部分柱状图的需求,同时添加延展动画
// 起始位置
CGFloat lastPointX = 100;
// 单位宽度
CGFloat itemWidth = 40;
// 相邻间隙
CGFloat itemPadding = 10;
// 图标高度
CGFloat chartHeight = 100;
// 数据
NSArray *dataArray = @[@180,@160,@140,@120,@160,@180,@200];
// 最大值
CGFloat maValue = [[dataArray valueForKeyPath:@"@max.floatValue"] floatValue];
for (NSInteger index = 0; index < dataArray.count; index++) {
NSInteger value = [dataArray[index] integerValue];
CGFloat height = value * 1.0 / maValue * chartHeight;
CGFloat y = 200 - height;
CGFloat x = lastPointX + itemWidth;
// 轨迹绘制
[bezierPath addLineToPoint:CGPointMake(lastPointX, y)];
[bezierPath addLineToPoint:CGPointMake(x, y)];
if (index != dataArray.count-1) {
[bezierPath addLineToPoint:CGPointMake(x, 200)];
[bezierPath moveToPoint:CGPointMake(x + itemPadding, 200)];
} else {
[bezierPath addLineToPoint:CGPointMake(x, 200)];
}
lastPointX = x+itemPadding;
}
//添加CAShapeLayer
CAShapeLayer * layer = [CAShapeLayer layer];
layer.fillColor = [UIColor redColor].CGColor;
layer.strokeColor = [UIColor redColor].CGColor;
layer.strokeStart = 0;
layer.strokeEnd = 1;
layer.zPosition = 1;
layer.lineWidth = 1;
layer.path = bezierPath.CGPath;
[self.view.layer addSublayer:layer];
// 添加动画 animationGroup 为动画代码
[layer addAnimation:[self pathAnimation] forKey:@"strokeEndAnimation"];
动画复用
- (CAAnimationGroup *)pathAnimation {
// 延展方向
CABasicAnimation * pathAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale.y"];
pathAnimation.fromValue = @0.0f;//动画开始位置
pathAnimation.toValue = @1.0f;//动画停止位置
// 延展值
CABasicAnimation *posAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
posAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(0,200)];
posAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(0,0)];
// 动画组合
CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
animationGroup.animations = @[pathAnimation,posAnimation];
animationGroup.duration = 0.3f;
animationGroup.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
animationGroup.removedOnCompletion = NO;
animationGroup.fillMode = kCAFillModeForwards;
return animationGroup;
}