重点:
获取绘制图形 Layer CAShapeLayer *shapeLayer = [CAShapeLayer layer];
设置图形有线颜色 [CAShapeLayer layer].strokeColor = [UIColor redColor].CGColor;
设置图形填充颜色 [CAShapeLayer layer].fillColor = [UIColor clearColor].CGColor;
设置图形线宽 [CAShapeLayer layer].lineWidth = 5;
图形连接类型 [CAShapeLayer layer].lineJoin = kCALineCapRound;
图形连接类型 [CAShapeLayer layer].lineCap = kCALineCapRound;
图形的路径 [CAShapeLayer layer].path = path.CGPath;
添加的图层上 [self.drawView.layer addSublayer:shapeLayer];
一、绘制火柴人
//绘制火柴人
UIBezierPath *path = [[UIBezierPath alloc] init];
[path moveToPoint:CGPointMake(175, 100)];
[path addArcWithCenter:CGPointMake(150, 100) radius:25 startAngle:0 endAngle:2*M_PI clockwise:YES];
[path moveToPoint:CGPointMake(150, 125)]; //正好是圆的半径位置,在圆的中心下文
[path addLineToPoint:CGPointMake(150, 175)]; //画一条50长的垂直直线,画身体
[path addLineToPoint:CGPointMake(125,225)]; //画一条向左且距离y轴有225的斜线,画左腿
[path moveToPoint:CGPointMake(150, 175)]; //再将起点移动到150,175的位置
[path addLineToPoint:CGPointMake(175, 225)];//画一条向右且距离y轴225的斜线,画右腿
[path moveToPoint:CGPointMake(125, 150)];
[path addLineToPoint:CGPointMake(175, 150)];//画双手
//create CAShapeLayer
CAShapeLayer *shapeLayer = [CAShapeLayer layer]; //得到layer
shapeLayer.strokeColor = [UIColor redColor].CGColor; //线的颜色
shapeLayer.fillColor = [UIColor clearColor].CGColor; //填充颜色
shapeLayer.lineWidth = 5; //线宽
//连接类型
shapeLayer.lineJoin = kCALineCapRound;
shapeLayer.lineCap = kCALineCapRound;
//路径添加到shapeLayer
shapeLayer.path = path.CGPath;
[self.drawView.layer addSublayer:shapeLayer];
图1
二、绘制特殊矩形(三个圆角,一个直角)
//三个是圆角,一个是直角,可以随意选择
CGRect rect = CGRectMake(50, 50, 100, 100);
CGSize radii = CGSizeMake(20, 20);
UIRectCorner corners = UIRectCornerTopLeft|UIRectCornerTopRight|UIRectCornerBottomLeft; //三个角
//画矩形
UIBezierPath *rectPath = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:corners cornerRadii:radii];
//路径添加到shapeLayer
shapeLayer.path = rectPath.CGPath;
[self.drawView.layer addSublayer:shapeLayer];
二、柱形图
重点:1. 熟练使用 CAShapeLayer绘制图形框架及UIBezierPath的学习。
2. C语言常用函数的使用,fabsf获取float类型的绝对值,ceil C语言中的取整。
1.添加柱形图上视图上
self.chartView = [[ChartView alloc] initWithFrame:CGRectMake(12*ScaleX, 64,mainWidth-24*ScaleX, 500-24*ScaleX)];
self.chartView.layer.cornerRadius = 4 ;
self.chartView.layer.shadowColor = UIColorFromRGB(0xff9300).CGColor;
self.chartView.layer.shadowOffset = CGSizeMake(1, 1);
self.chartView.layer.shadowOpacity = 0.2;
[self.view addSubview:self.chartView];
2.设置柱形图数据
[self refreshWithArray:@[@"600.00",@"6.91",@"1310.00",@"600.00",@"0.00",@"-800.00",@"0.00",@"152.00",@"-30.00",@"0.00"]];
- (void)refreshWithArray:(NSArray *)returnArray{
NSMutableArray *tempArray = [NSMutableArray arrayWithArray:returnArray];
// 数组个数不够10个
if (returnArray.count < 10) {
// 插入的次数
for (int i = 0; i<10-returnArray.count; i++) {
[tempArray insertObject:[NSNumber numberWithInt:0] atIndex:(returnArray.count)];
}
}
// 数组个数多于10个
if (returnArray.count > 10) {
for (int i = 0; i<returnArray.count - 10; i++) {
[tempArray removeObjectAtIndex:0];
}
}
// 如果数组的元素不是数字类型
NSMutableArray *resultArray = [NSMutableArray array];
for (int i = 0; i<tempArray.count; i++) {
if (![tempArray[i] isKindOfClass:[NSNumber class]]) {
NSString *tempString = [NSString stringWithFormat:@"%@",tempArray[i]];
[resultArray addObject:[NSNumber numberWithFloat:tempString.floatValue]];
}else{
[resultArray addObject:tempArray[i]];
}
}
self.chartView.datas = resultArray;
[self.chartView show];
}
3.加载UI及设置数据
#import <UIKit/UIKit.h>
@interface ChartView : UIView
@property (nonatomic, strong) NSArray *datas;
- (void)show;
@end
#import "ChartView.h"
#define STRChartLeftWidth 60
#define STRChartColorFromRGB(rgbValue) [UIColor \
colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 \
green:((float)((rgbValue & 0xFF00) >> 8))/255.0 \
blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]
@interface ChartView()
@property (nonatomic, assign) CGFloat maxValue;
@property (nonatomic, strong) NSMutableArray *yArray;
@property (nonatomic, strong) CAShapeLayer *backGroundLayer;
@property (nonatomic, strong) UIBezierPath *backGroundPath;
@property (nonatomic, strong) CATextLayer *backGroundTextLayer;
// 画图的间距
@property (nonatomic,assign) CGFloat minWidth;
@property (nonatomic,assign) CGFloat minHeight;
@end
@implementation ChartView
#pragma mark - ♻️life cycle
- (instancetype)initWithFrame:(CGRect)frame{
if (self = [super initWithFrame:frame]) {
[self loadUI];
}
return self;
}
- (instancetype)init
{
self = [super init];
if (self) {
[self loadUI];
}
return self;
}
- (void)loadUI{
self.yArray = [NSMutableArray array];
self.backgroundColor = [UIColor whiteColor];
self.minWidth = (self.bounds.size.width - STRChartLeftWidth - 10)/(11+10*2);
self.minHeight = self.bounds.size.height/10;
}
#pragma mark - ?overwrite
- (void)setDatas:(NSArray *)datas{
_datas = datas;
NSMutableArray *tempArray = [NSMutableArray array];
for (int i = 0; i<datas.count; i++) {
NSString *tempStr = [NSString stringWithFormat:@"%@",datas[i]];
NSNumber *tempNum = [NSNumber numberWithFloat:fabsf(tempStr.floatValue)];
[tempArray addObject:tempNum];
}
// 获取最大值
self.maxValue = [[tempArray valueForKeyPath:@"@max.floatValue"] floatValue];
// ceil函数,向上取整
int num = (ceil((self.maxValue / 200.00)))*200;
// y坐标数组
for (int i = 0; i<9; i++) {
[self.yArray addObject:[NSString stringWithFormat:@"%d",(num - num/4 * i)]];
}
// 关键是最大刻度
self.maxValue = num;
}
4、画图形
- (void)show{
self.layer.sublayers = nil;
[self p_drawBackGroundPath]; //和数组无关
[self p_drawBackGroundText];
[self p_drawBackBar];
}
- (void)p_drawBackBar{
//未完待续
}
- (void)p_drawBackGroundText{
//也可以用label
//画文字
for (NSInteger i = 0; i <self.yArray.count ; i++) {
self.backGroundTextLayer = [CATextLayer layer];
self.backGroundTextLayer.string = [NSString stringWithFormat:@"%@元",self.yArray[i]];
NSString *text = self.yArray[i];
if (text.floatValue<0) {
self.backGroundTextLayer.foregroundColor = UIColorFromRGB(0x00CE64).CGColor;
self.backGroundTextLayer.string = [NSString stringWithFormat:@"%@元",self.yArray[i]];
}else if (text.floatValue>0){
self.backGroundTextLayer.foregroundColor = UIColorFromRGB(0xFF5376).CGColor;
self.backGroundTextLayer.string = [NSString stringWithFormat:@"+%@元",self.yArray[i]];
}else{
self.backGroundTextLayer.foregroundColor = UIColorFromRGB(0x878787).CGColor;
}
self.backGroundTextLayer.fontSize = 10;
self.backGroundTextLayer.alignmentMode = kCAAlignmentRight;
self.backGroundTextLayer.contentsScale = [UIScreen mainScreen].scale;// 使字体不模糊 屏幕分辨率原因
self.backGroundTextLayer.frame = CGRectMake(0,self.minHeight-10+i*self.minHeight, 50, 20);
[self.layer addSublayer:self.backGroundTextLayer];
}
}
- (void)p_drawBackGroundPath{
self.backGroundLayer = [CAShapeLayer layer];
[self.layer addSublayer:self.backGroundLayer];
self.backGroundLayer.frame = self.bounds;
self.backGroundPath = [UIBezierPath bezierPath];
NSInteger lineNum = 9;
for (NSInteger i = 0; i< lineNum; i++) {
[self.backGroundPath moveToPoint:CGPointMake(STRChartLeftWidth,i*self.minHeight+self.minHeight)];
[self.backGroundPath addLineToPoint:CGPointMake(self.bounds.size.width - 10,i*self.minHeight+self.minHeight)];
}
//线的宽度
self.backGroundLayer.lineWidth = 1.0;
//线的颜色
self.backGroundLayer.strokeColor = STRChartColorFromRGB(0xD8D7D7).CGColor;
//将self.backGroundPath的路径设置到path
self.backGroundLayer.path = self.backGroundPath.CGPath;
//将上面的实线设置为虚线
[self.backGroundLayer setLineDashPattern:[NSArray arrayWithObjects:[NSNumber numberWithInt:1], [NSNumber numberWithInt:1], nil]];
//画中间的实线
CAShapeLayer *centerLine = [CAShapeLayer layer];
[self.layer addSublayer:centerLine];
centerLine.frame = CGRectMake(STRChartLeftWidth,self.frame.size.height/2-0.5,self.bounds.size.width - STRChartLeftWidth -20, 1);
centerLine.backgroundColor = STRChartColorFromRGB(0xF0F0F0).CGColor;
}
@end