美文网首页
iOS ----Core Graphics(1):画线

iOS ----Core Graphics(1):画线

作者: 阿丶伦 | 来源:发表于2017-02-03 15:40 被阅读281次

    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.png

    line,我们绘制的是线段,所以,上面设置线宽的方法,明显是我们需要的.基本都介绍完了,上代码.

        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提供了一系列的监听方法...我们直接在相应方法里操作就好了.
    Paste_Image.png

    首先,我们需要两个数组...一个存放组成线段的点...一个存放线段...

    /**存放每条线*/
    @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

    成果如下,请忽略界面美观度,后续会继续完善.


    先写到这里,后续更新,感谢观看...若有错误,请斧正.

    相关文章

      网友评论

          本文标题:iOS ----Core Graphics(1):画线

          本文链接:https://www.haomeiwen.com/subject/zlydittx.html