iOS绘制图形实战
Posted 太书红叶
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS绘制图形实战相关的知识,希望对你有一定的参考价值。
本文结构:想看吐槽直接跳到末尾。
- 前言
- 正文
- 结尾扯犊子
前言
最近做了ios开发。
当一天和尚撞一天钟呗。身心俱疲。贼难受,没看我都不更新博客了么。
iOS的绘制,看了好多帖子,忘了都是哪些帖子了,感谢前辈们。不贴看过的链接了,因为看得太多了。
要是片的话,看过多少我都能熟记于心。那手法,那。。。不说了。
结尾扯点犊子,唠点嗑,也就行了。
正文
需求
最近接到这样一个需求。需求中有一个地方是这样的:
这个地方没有给背景图,看了一下基本都是直线,那就自己画一个吧,iOS还不会自定义view呢,正好熟悉一下绘制。
发现他们是排着队,一个一个插着下一个人的后面吗,这样就考虑计算一下上一个图形的尖尖插了自己的pp,所带来的影响,再来画下一个图形了。
实现思路
刚开始就想着自己绘制,那就需要新建一个继承自UIview的控件,然后开始画线,然后再绘制文字。
后来动起手来发现,文字部分不如直接用UILabel,来的快,他的sizeToFit也方便我们测量他的宽高。
于是思路变成了这样:
定义一个数组变量,由外部传入,为需要的文本数组,如图中的”好友如\\n何助力“、”打开分享链接“等。遍历此数组,实例化UIlabel,根据UIlabel的宽高计算出要画的线的各个坐标。
定义两个颜色,开始颜色和结束颜色,外部传入此控件中。获取颜色的rgb值,遍历数组时,设置对应的颜色。
如图所示:每一个图形都需要计算6个点,画5条线,需要特殊处理的地方就是第一个图形,他在计算的时候,不用受上一个图形的影响,只需要计算5个点,因为他不像其他的图形,有上一个的尖尖插着自己的pp。
最后一个图形,可以不画这个尖尖,也可以画出来,然后利用setMasksToBounds。
有了思路就开始做了。
代码
我的代码为什么是红色的
.h文件:
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface BRStepView : UIView
@property(nonatomic,strong)NSArray *strData;
@property(nonatomic,strong)NSArray *colorArray;
@property(nonatomic,strong)UIColor *startColor;
@property(nonatomic,strong)UIColor *endColor;
@end
NS_ASSUME_NONNULL_END
.m文件:
CommonUtil 是个工具类,用它调用相关方法的作用大家可以顾名思义。
#import "BRStepView.h"
#import "CommonUtil.h"
@implementation BRStepView
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
// Drawing code
*/
//初始化
- (instancetype)initWithFrame:(CGRect)frame
self = [super initWithFrame:frame];
if (self)
[self setBackgroundColor:[UIColor colorWithRed:0.87 green:0.87 blue:0.87 alpha:1]];
return self;
//绘制的主要方法
- (void)drawRect:(CGRect)rect
if (!self.strData)
//self.strData这个就是数据源,没有数据源,不进行绘制。
return;
//定义起始、终止颜色的rgb值
CGFloat red = 0.0;
CGFloat green = 0.0;
CGFloat blue = 0.0;
CGFloat alpha = 0.0;
CGFloat endRed = 0.0;
CGFloat endGreen = 0.0;
CGFloat endBlue = 0.0;
CGFloat endAlpha = 0.0;
if (self.startColor && self.endColor)
//没设置就是0,也就是默认黑色
//获取rgb值:
[self.startColor getRed:&red green:&green blue:&blue alpha:&alpha];
[self.endColor getRed:&endRed green:&endGreen blue:&endBlue alpha:&endAlpha];
CGContextRef con = UIGraphicsGetCurrentContext();//获取绘制的上下文,每一个绘制方法都需要此参数
CGContextSetLineWidth(con, 1.0);//设置绘制的线宽
CGFloat pointX = 0;//label的x
CGFloat pointTopX = 0;//顶部的点
NSInteger count = self.strData.count;
for (int i = 0; i < self.strData.count; i++)
//每个颜色的值的算法:因为是要进行平均的变色,来达到循序渐进的效果。所以用起始的rgb值-终止的gbr值。所得值除以总数,算出每两个图形之间的颜色差值,根据是第几个就乘以几。然后再加上起始颜色的rgb的值,就是当前要设置的颜色。注意,alpha不用变?。
UIColor *color = [UIColor colorWithRed:(fabs(red-endRed)/count*(i+1) + MIN(red, endRed)) green:(fabs(green-endGreen)/count*(i+1) + MIN(green,endGreen)) blue:(fabs(blue-endBlue)/count*(i+1) + MIN(blue, endBlue)) alpha:1];
[color set];
UILabel *label = [[UILabel alloc]init];
[label setFont:[CommonUtil getFontWithFontName:@"PingFangSC-Regular" andFontSize:12]];
[label setTextColor:[CommonUtil colorWithHexString:@"#333333"]];
NSString *text = self.strData[i];
[label setText:text];
[label setNumberOfLines:0];
[label sizeToFit];//下面会利用label的frame来计算
[self addSubview:label];
CGContextSetFillColorWithColor(con, color.CGColor);//线颜色
CGContextMoveToPoint(con, pointTopX, 0);//起始点
if (i == 0) //第一个图形,不用计算上一个图形的尖尖
CGContextAddLineToPoint(con, pointTopX + CGRectGetWidth(label.frame) + 10 + 5, 0);//label左测留白10右侧留白5,留白就是传说中的margin
if (i != self.strData.count - 1)//不是最后一个
CGContextAddLineToPoint(con, pointTopX + CGRectGetWidth(label.frame) + 10 + 5 + 15, CGRectGetHeight(self.frame)/2);
CGContextAddLineToPoint(con, pointTopX + CGRectGetWidth(label.frame) + 10 + 5, CGRectGetHeight(self.frame));
else
//最后一个不画这个尖,直接画到头
CGContextAddLineToPoint(con, CGRectGetWidth(self.frame) + 10 + 5, CGRectGetHeight(self.frame));
CGContextAddLineToPoint(con, pointTopX, CGRectGetHeight(self.frame));
else//非第一个图形,需要计算上一个图形的尖尖,因为他插了自己pp。
if (i != self.strData.count - 1)
CGContextAddLineToPoint(con, pointTopX + CGRectGetWidth(label.frame) + 10 + 5 + 15, 0);//label再加前一个尖
CGContextAddLineToPoint(con, pointTopX + CGRectGetWidth(label.frame) + 10 + 5 + 15 + 15, CGRectGetHeight(self.frame)/2);
CGContextAddLineToPoint(con, pointTopX + CGRectGetWidth(label.frame) + 10 + 5 + 15, CGRectGetHeight(self.frame));
else
//最后一个不画这个尖,直接画到头
CGContextAddLineToPoint(con, CGRectGetWidth(self.frame), 0);//label再加前一个尖
CGContextAddLineToPoint(con, CGRectGetWidth(self.frame), CGRectGetHeight(self.frame));
CGContextAddLineToPoint(con, pointTopX, CGRectGetHeight(self.frame));
CGContextAddLineToPoint(con, pointTopX + 15, CGRectGetHeight(self.frame)/2);
CGContextFillPath(con);//封闭,关门放狗
//开始计算下一个图形的相关位置
if (i != 0) //第一个图形,不用计算上一个图形的尖尖
pointTopX = pointTopX + CGRectGetWidth(label.frame) + 10 + 5 +15;//label左10右5 尖15
else//非第一个图形,需要计算上一个图形的尖尖,因为他插了自己pp。
pointTopX = pointTopX + CGRectGetWidth(label.frame) + 10 + 5;//label左10右5
pointX += 10;//左侧10
//放置奇兵
label.center = CGPointMake(pointX + CGRectGetWidth(label.frame)/2, CGRectGetHeight(self.frame)/2);
pointX += CGRectGetWidth(label.frame) +5;
pointX += 15;
@end
代码写的垃圾,刷几天LeetCode吧。今天看到一个LeetCode的快速刷题的插件,想试试。真好。
扯犊子
在这扯:
https://blog.csdn.net/u014540814/article/details/87855504
以上是关于iOS绘制图形实战的主要内容,如果未能解决你的问题,请参考以下文章
R语言使用ggpubr包绘制出版社编辑审稿人要求的可视化图形实战
OpenCV-Python实战——OpenCV中绘制图形与文本(万字总结,️❤️建议收藏️❤️)