iOS开发UI篇——Core Animation核心动画CAShapeLayer(绘制图形等)简介
重点:
获取绘制图形 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];
一、绘制火柴人
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | //绘制火柴人 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
二、绘制特殊矩形(三个圆角,一个直角)
1 2 3 4 5 6 7 8 9 | //三个是圆角,一个是直角,可以随意选择 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.添加柱形图上视图上
1 2 3 4 5 6 | 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.设置柱形图数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | [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及设置数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | #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、画图形
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | - ( 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 |
将来的自己,会感谢现在不放弃的自己!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现