iOS绘图

2018-11-08  本文已影响9人  cxlhaha

前言

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

如何绘图

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

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

 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();
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:方法获取图形上下文

-(void)drawRect:(CGRect)rect
{
    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 200, 200)];
    [path fill];
    
}
-(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)];
   
上一篇下一篇

猜你喜欢

热点阅读