iOS绘图

作者: cxlhaha | 来源:发表于2018-11-08 15:05 被阅读9次

    前言

    当遇到绘图需求的时候我们就需要利用UIKit或者是CoreGraphics这两个绘图框架进行绘图,而这两个框架之间的关系是这样的:

    • CoreGraphics是绘图方面的基础,它提供了大量的API满足我们各种各样的绘图需求,但是,因为CoreGraphics更加底层,是一套C语言的框架,所以,UIKit帮我们进行了封装,我们可以利用UIKit简洁的语法,快速的实现绝大多数的绘图需求。所以当绘图需求简单,我们想要快速实现时,我们可以利用UIKit进行绘图,而如果需要全部功能的绘图需求,我们就选择功能强大的CoreGraphics进行绘图。

    • UIKit只能在当前上下文中进行绘图,如果不是当前上下文需要转化为当前上下文再进行绘图。

    如何绘图

    因为我们需要在图形上下文上进行绘图,这里有两种常用的获取图形上下文的方式:

    方式一:创建图片类型上下文

    • UIKit实现:
     UIGraphicsBeginImageContext(CGSizeMake(200, 200));
        
        [[UIColor greenColor] set];
        UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 200, 200)];
        [path fill];
        UIImageView *imgView = [[UIImageView alloc]initWithImage:UIGraphicsGetImageFromCurrentImageContext()];
        imgView.frame = CGRectMake(100, 100, 200, 200);
        [self.view addSubview:imgView];
        
        UIGraphicsEndImageContext();
    
    • CoreGraphics实现:
    UIGraphicsBeginImageContext(CGSizeMake(200, 200));
        CGContextRef con = UIGraphicsGetCurrentContext();
        CGContextAddEllipseInRect(con, CGRectMake(0, 0, 200, 200));
        CGContextSetFillColorWithColor(con, [UIColor greenColor].CGColor);
        CGContextFillPath(con);
        UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
        UIImageView *imgView = [[UIImageView alloc]initWithImage:img];
        imgView.frame = CGRectMake(0, 0, 200, 200);
        [self.view addSubview:imgView];
        
        UIGraphicsEndImageContext();
    

    方式二:drawRect:方法获取图形上下文

    • UIKit实现:
    -(void)drawRect:(CGRect)rect
    {
        UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 200, 200)];
        [path fill];
        
    }
    
    • CoreGraphics实现:
    -(void)drawRect:(CGRect)rect
    {
        CGContextRef con = UIGraphicsGetCurrentContext();
        CGContextAddEllipseInRect(con, CGRectMake(0, 0, 200, 200));
        CGContextFillPath(con);
        
    }
    

    性能问题

    值得注意的是,当我们进行绘图的时候,有时候会出现性能问题。
    比如说:当我们要实现一个画板功能时,我们首先想到的是重写drawRect方法,进行绘图,但是当画板足够大时,我们会发现,绘图时内存会暴增。这是因为,调用drawRect方法时,会生成系统会生成寄宿图,渲染前都会保存这张图片,当画板足够大时,就会导致内存暴增。当然有一些方法可以优化,我这里就不展开分析,我要说的是,最好的优化就是不去绘图,比如,那个画板需求,我们可以用CAShapeLayer实现,我们就会发现性能稳定多了,下面我就把两种实现的代码贴出来,有兴趣的同学自己尝试一下就会发现差别。

    drawRect:

    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        CGPoint point =  [touches.anyObject locationInView:self];
        UIBezierPath *path = [UIBezierPath bezierPath];
        [path moveToPoint:point];
        [self.pathArray addObject:path];
    
    }
    -(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        CGPoint point = [touches.anyObject locationInView:self];
        UIBezierPath *path = self.pathArray.lastObject;
        [path addLineToPoint:point];
    
        [self setNeedsDisplay];
    }
    
    -(void)drawRect:(CGRect)rect
    {
        for (UIBezierPath *path  in self.pathArray) {
            [path stroke];
        }
    
    }
    

    CAShapeLayer:

    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        CGPoint point = [touches.anyObject locationInView:self];
        
        UIBezierPath *path = [UIBezierPath bezierPath];
        path.lineWidth = 5;
        [path moveToPoint:point];
        self.lastPath = path;
        
        CAShapeLayer *sLayer = [CAShapeLayer layer];
        sLayer.strokeColor = [UIColor blackColor].CGColor;
        sLayer.fillColor = [UIColor clearColor].CGColor;
        [self.layer addSublayer:sLayer];
        
    }
    
    -(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
       CGPoint point = [touches.anyObject locationInView:self];
        [self.lastPath addLineToPoint:point];
        
        CAShapeLayer *slayer= self.layer.sublayers.lastObject;
        slayer.path = self.lastPath.CGPath;
    }
    

    其它内容的绘图

    • 文字绘制
    NSString *str = @"fdfas";
    
        [str drawInRect:CGRectMake(100, 100, 100, 100) withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:15],NSForegroundColorAttributeName:[UIColor greenColor]}];
    
    • 图像绘制
        UIImage *image = [UIImage imageNamed:@"121"];
        
       [image drawInRect:CGRectMake(0, 0, 100, 100)];
       
    

    相关文章

      网友评论

          本文标题:iOS绘图

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