iOS UIBezierPath、CAShapeLayer绘制柱
2020-03-21 本文已影响0人
Joymerry
柱状图——数据筛选
只要明白贝塞尔曲线的原理,样式随便变动
主要介绍如何实现柱状图功能
.h实现
@property (nonatomic,assign) double leftMargin;//左右边距
@property (nonatomic,assign) double bottomMargin;//上下边距
@property (nonatomic,assign) double horizontalMargin;//水平间距
@property (nonatomic,assign) double verticalMargin;//竖直间距
@property (nonatomic,assign) double priceLabelWidth;//y轴label宽度
@property (nonatomic,assign) double priceLabelHeight;//y轴label的高度
@property (nonatomic,assign) double columnWidth;//柱宽
@property (nonatomic,strong) NSArray * verticalArray;//y轴数组
@property (nonatomic,assign) double valuesMargin;//y轴数值间隔
@property (nonatomic,strong) NSArray * dateArray;//日期数组
@property (nonatomic,strong) NSArray * priceArray;//价格数组
@property (nonatomic,strong) NSArray * weightArray;//成交量数组
/**
* 画柱状图
* @param x_names x轴值的所有值名称
* @param targetValues 所有目标值(用于计算坐标)
* @param realValues 真实目标值
*/
-(void)drawBarChartViewWithX_Value_Names:(NSMutableArray *)x_names TargetValues:(NSMutableArray *)targetValues ;
.m实现代码
/**
* 画柱状图
*/
-(void)drawBarChartViewWithX_Value_Names:(NSMutableArray *)x_names TargetValues:(NSMutableArray *)targetValues
{
//1.画坐标轴
[self drawXYLine:x_names];
//2.每一个目标值点坐标
for (int i=0; i < targetValues.count; i++) {
//10为坐标间距
CGFloat doubleValue = [targetValues[i] floatValue]/self.valuesMargin*self.verticalMargin; //目标值放大
CGFloat X = self.leftMargin + self.priceLabelWidth + (self.horizontalMargin+self.columnWidth)*I;
//CGFloat X = self.leftMargin + self.horizontalMargin*(i+1)+5;
CGFloat Y = CGRectGetHeight(myFrame)-self.bottomMargin-doubleValue;
UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(X, Y, self.columnWidth, doubleValue)];
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.path = path.CGPath;
shapeLayer.strokeColor = [UIColor clearColor].CGColor;
shapeLayer.fillColor = XYQColor(0, 124, 104).CGColor;
shapeLayer.borderWidth = 2.0;
[self.subviews[0].layer addSublayer:shapeLayer];
//新建一个按钮,透明 覆盖shapeLayer
UIButton * btn = [[UIButton alloc]init];
btn.frame = CGRectMake(X, Y, self.columnWidth, doubleValue);
btn.backgroundColor = [UIColor clearColor];
btn.tag = 1000 + I;
[btn addTarget:self action:@selector(targetButtonClick:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:btn];
if (i == targetValues.count - 1 && _dateArray.count > 0)
{
btn.backgroundColor = RGBA(255, 255, 255, 0.5);
lastTag = 1000 + I;
NSString * titleOne = [NSString stringWithFormat:@"%@",_dateArray[I]];
NSString * titleTwo = [NSString stringWithFormat:@"%ld",[_priceArray[i] longValue]];
NSString * titleThree = [NSString stringWithFormat:@"%ld",[_weightArray[i] longValue]];
NSString *str1 = [titleOne substringToIndex:10];//截取掉下标10之前的字符串
NSString *str2 = [str1 substringFromIndex:8];//截取掉下标8之后的字符串
NSString * str3 = [str1 substringToIndex:7];
NSString * str4 = [str3 substringFromIndex:5];
NSString * dateStr = [NSString stringWithFormat:@"%@月%@日",str4,str2];
NSString * title = [NSString stringWithFormat:@"%@ # %.2f元/吨 成交量%.3f吨",dateStr,[titleTwo doubleValue],[titleThree doubleValue]];
titleLabel.hidden = NO;
titleLabel.text = title;
}
}
}
/**
* 画坐标轴
*/
-(void)drawXYLine:(NSMutableArray *)x_names{
UIBezierPath *path = [UIBezierPath bezierPath];
UILabel * priceLabel = [[UILabel alloc]init];
priceLabel.frame = CGRectMake(self.leftMargin, 5, 35, 15);
priceLabel.text = @"价格:¥";
priceLabel.textColor = [UIColor whiteColor];
priceLabel.font = [UIFont systemFontOfSize:8.0];
[self addSubview:priceLabel];
UILabel * firstLabel = [[UILabel alloc]init];
firstLabel.frame = CGRectMake(self.leftMargin,CGRectGetHeight(myFrame)-self.bottomMargin, self.priceLabelWidth, 20);
firstLabel.text = @"最近一周";
firstLabel.textColor = [UIColor whiteColor];
firstLabel.font = [UIFont systemFontOfSize:8.0];
firstLabel.adjustsFontSizeToFitWidth = YES;
[self addSubview:firstLabel];
//1.Y轴、X轴的直线
[path moveToPoint:CGPointMake(self.leftMargin, CGRectGetHeight(myFrame)-self.bottomMargin)];
[path addLineToPoint:CGPointMake(self.leftMargin+CGRectGetWidth(myFrame)-2*self.leftMargin, CGRectGetHeight(myFrame)-self.bottomMargin)];
//2.添加箭头
// [path moveToPoint:CGPointMake(MARGIN, MARGIN)];
// [path addLineToPoint:CGPointMake(MARGIN-5, MARGIN+5)];
// [path moveToPoint:CGPointMake(MARGIN, MARGIN)];
// [path addLineToPoint:CGPointMake(MARGIN+5, MARGIN+5)];
//
// [path moveToPoint:CGPointMake(MARGIN+CGRectGetWidth(myFrame)-2*MARGIN, CGRectGetHeight(myFrame)-MARGIN)];
// [path addLineToPoint:CGPointMake(MARGIN+CGRectGetWidth(myFrame)-2*MARGIN-5, CGRectGetHeight(myFrame)-MARGIN-5)];
// [path moveToPoint:CGPointMake(MARGIN+CGRectGetWidth(myFrame)-2*MARGIN, CGRectGetHeight(myFrame)-MARGIN)];
// [path addLineToPoint:CGPointMake(MARGIN+CGRectGetWidth(myFrame)-2*MARGIN-5, CGRectGetHeight(myFrame)-MARGIN+5)];
//3.添加索引格
//X轴
for (int i=0; i<x_names.count; i++) {
CGFloat X = self.leftMargin + self.priceLabelWidth + (self.horizontalMargin+self.columnWidth)*I;
CGPoint point = CGPointMake(X,CGRectGetHeight(myFrame)-self.bottomMargin);
[path moveToPoint:point];
[path addLineToPoint:CGPointMake(point.x, point.y-3)];
}
//Y轴(实际长度为200,此处比例缩小一倍使用)
for (int i=0; i < self.verticalArray.count; i++) {
CGFloat Y = CGRectGetHeight(myFrame)-self.bottomMargin-self.verticalMargin*I;
CGPoint point = CGPointMake(self.leftMargin,Y);
[path moveToPoint:point];
[path addLineToPoint:CGPointMake(point.x+CGRectGetWidth(myFrame)-2*self.leftMargin, point.y)];
}
//4.添加索引格文字
//X轴
for (int i=0; i<x_names.count; i++) {
CGFloat X = self.leftMargin + self.priceLabelWidth + (self.horizontalMargin+self.columnWidth)*i - self.horizontalMargin/2.0 + self.columnWidth/2.0;
UILabel *textLabel = [[UILabel alloc] initWithFrame:CGRectMake(X, CGRectGetHeight(myFrame)-self.bottomMargin, self.horizontalMargin, 20)];
textLabel.text = x_names[I];
textLabel.font = [UIFont systemFontOfSize:8];
textLabel.textAlignment = NSTextAlignmentCenter;
textLabel.textColor = XYQColor(244, 244, 244);
[self addSubview:textLabel];
}
//Y轴
for (int i=0; i < self.verticalArray.count; i++) {
CGFloat Y = CGRectGetHeight(myFrame)-self.bottomMargin-self.verticalMargin*I;
UILabel *textLabel = [[UILabel alloc] initWithFrame:CGRectMake(self.leftMargin, Y-10,self.priceLabelWidth, 10)];
textLabel.text = [NSString stringWithFormat:@"%@",self.verticalArray[I]];
textLabel.font = [UIFont systemFontOfSize:8.0];
textLabel.textAlignment = NSTextAlignmentLeft;
textLabel.textColor = XYQColor(204, 204, 204);
[self addSubview:textLabel];
}
//5.渲染路径
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.path = path.CGPath;
shapeLayer.lineWidth = 0.2;
shapeLayer.strokeColor = [UIColor whiteColor].CGColor;
shapeLayer.fillColor = [UIColor clearColor].CGColor;
shapeLayer.borderWidth = 0.5;
[self.subviews[0].layer addSublayer:shapeLayer];
//
titleLabel = [[UILabel alloc]init];
titleLabel.frame = CGRectMake(priceLabel.right, 5, self.width - self.leftMargin - priceLabel.right, 20);
titleLabel.layer.masksToBounds = YES;
titleLabel.layer.cornerRadius = titleLabel.height / 2.0;
titleLabel.backgroundColor = kMainColor;
titleLabel.hidden = YES;
titleLabel.font = [UIFont systemFontOfSize:12.0];
titleLabel.textAlignment = NSTextAlignmentCenter;
titleLabel.textColor = [UIColor whiteColor];
titleLabel.adjustsFontSizeToFitWidth = YES;
[self addSubview:titleLabel];
}
这是主要实现的逻辑,而真正用到的也就是UIBezierPath、CAShapeLayer。
我们主要讲讲这两个类的作用。