demo地址:https://github.com/allenchann/CWLGraphics
drawRect(UIImageView不会调用该方法)
画线
CGContextRef(上下文对象)
Paste_Image.png如图所示,它是绘图的环境所在,所以我们所有的绘制处理,都是基于他.
CGContextRef context = UIGraphicsGetCurrentContext();
这句代码,我们可以获得当前view的上下文对象.
Paste_Image.png
我们需要在UIView下的drawRect方法下获取,所以一般,我们都是通过重写UIView的子类来进行相关操作.
绘制环境有了,那接下来,就需要一条绘制的通道.
Paste_Image.png
path,使我们绘制的通道.从API提供的方法看,只会有一条通道存在.第三个方法说得很清楚,它可以添加一条线段从当前的点到我们设定的点.那当前的点我们怎么知道呢.看它上面的方法,我们可以通过它,来确定开始绘制的点.
Paste_Image.pngline,我们绘制的是线段,所以,上面设置线宽的方法,明显是我们需要的.基本都介绍完了,上代码.
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 3); //线宽
CGContextBeginPath(context);
CGContextMoveToPoint(context, 0, 0);
CGContextAddLineToPoint(context, 50, 100);
CGContextAddLineToPoint(context, 51, 101);
CGContextStrokePath(context);
Paste_Image.png
想要画的线段就画出来了...记住,一定要调用CGContextStrokePath方法,不然路径中的所有操作,都不会绘制到视图上.
上面已经知道怎么画线了...下面,我们可以用这个来玩玩画画啊...
先捋一下思路...要画画,我们需要什么
- 画笔:好牛逼的样子...其实就是手指呗...模拟器的话...就是你的鼠标指针呗...那我们怎么捕捉到当前的屏幕操作呢...UIView提供了一系列的监听方法...我们直接在相应方法里操作就好了.
首先,我们需要两个数组...一个存放组成线段的点...一个存放线段...
/**存放每条线*/
@property (nonatomic, strong) NSMutableArray *lineArr;
/**存放一条线里所有点*/
@property (nonatomic, strong) NSMutableArray *pointArr;
/**线段数组*/
- (NSMutableArray *)lineArr
{
if (!_lineArr) {
NSMutableArray *arr = [[NSMutableArray alloc]init];
_lineArr = arr;
}
return _lineArr;
}
做一个懒加载,有人会问,点数组为什么不做懒加载,我就不多解释了...
接下来,我们在开始移动的时候,让点数组把当前起点作为第一个元素,然后在移动过程中,把每个点添加进点数组中,组合后,就是一段线段了.
为什么在一开始就把点数组添加进线数组中,是因为在移动方法中,把点添加进点数组时,线数组中的元素也会相应改变...因为addObject方法,使用的是copy,指针还是同一个.
我们要实时看到线段的效果,就在移动过程中,调用display方法,让视图实时重绘.上代码
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//初始化点数组
self.pointArr = [[NSMutableArray alloc]init];
//点数组添加第一个元素
[self.pointArr addObject:[NSValue valueWithCGPoint:[touches.anyObject locationInView:self]]];
//把当前线段加进线数组中
[self.lineArr addObject:self.pointArr];
}
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//添加点
[self.pointArr addObject:[NSValue valueWithCGPoint:[touches.anyObject locationInView:self]]];
//重绘视图
[self setNeedsDisplay];
}
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
}
线跟点都有了,我们要怎么绘制呢...上面我们已经知道怎么画线了,那么,开始吧,我们写一个画线的方法.
- (void)drawLine:(NSArray *)line {
//判断是否有线
if (line.count>0) {
//获取当前上下文对象
CGContextRef context = UIGraphicsGetCurrentContext();
//通道开始
CGContextBeginPath(context);
//遍历线数组
for (NSArray *pointArr in line) {
//获取起点
CGPoint startPoint = [pointArr[0] CGPointValue];
//移动到绘制点
CGContextMoveToPoint(context, startPoint.x, startPoint.y);
//判断是否应该画线,并开始添加点
if (pointArr.count>1) {
for (int i=1; i<pointArr.count; i++) {
CGPoint linePoint = [pointArr[i] CGPointValue];
CGContextAddLineToPoint(context, linePoint.x, linePoint.y);
}
}
}
//画线
CGContextStrokePath(context);
}
}
然后,我们在 drawRect方法中,调用就好了...
- (void)drawRect:(CGRect)rect {
//画线
[self drawLine:self.lineArr];
}
画是能画了...但是黑抹抹的...没有粗细...画完也不能清空撤销...不太好...我们可以稍微丰富一下...篇幅太长,不一一把具体实现都写出,主要贴出绘制时的方法,感兴趣的朋友可以下载demo查看
- (void)drawLine:(NSArray *)line {
//判断是否有线
if (line.count>0) {
//遍历线数组
for (NSArray *pointArr in line) {
//获取当前上下文对象
CGContextRef context = UIGraphicsGetCurrentContext();
//通道开始
CGContextBeginPath(context);
//线宽
float width = [self.lineWidthArr[[line indexOfObject:pointArr]] floatValue];
//线颜色
UIColor *color = self.lineColorArr[[line indexOfObject:pointArr]];
//设置线宽
CGContextSetLineWidth(context, width);
//设置线条颜色
CGContextSetStrokeColorWithColor(context, color.CGColor);
//获取起点
CGPoint startPoint = [pointArr[0] CGPointValue];
//移动到绘制点
CGContextMoveToPoint(context, startPoint.x, startPoint.y);
//判断是否应该画线,并开始添加点
if (pointArr.count>1) {
for (int i=1; i<pointArr.count; i++) {
CGPoint linePoint = [pointArr[i] CGPointValue];
CGContextAddLineToPoint(context, linePoint.x, linePoint.y);
}
}
//画线
CGContextStrokePath(context);
}
}
}
有人注意到,我把开辟通道的方法,写进了循环里...这是因为如果不每次开开辟通道的话,会默认使用一条通道,通道里的颜色粗细,都会变成统一的,意义就不存在了...
Paste_Image.png成果如下,请忽略界面美观度,后续会继续完善.
先写到这里,后续更新,感谢观看...若有错误,请斧正.
网友评论