美文网首页贝塞尔曲线
iOS 三种线的绘制方式 : CGContextRef CG

iOS 三种线的绘制方式 : CGContextRef CG

作者: 王技术 | 来源:发表于2019-03-05 15:15 被阅读0次

    都是平时常用的东西
    不整理一下的话总感觉有点乱
    这三种东西:CGContextRef CGPath UIBezierPath
    本质上都是一样的
    都是使用 Quartz 来绘画
    只不过把绘图操作暴露在不同的 API 层面上
    在具体实现上
    也会有一些细小的差别


    1 - UIBezierPath 方式

    首先使用 UIBezierPath 类型绘制
    UIBezierPath 包装了Quartz的相关API
    自己存在于UIKit中
    因此不是基于C的API
    而是基于Objective-C对象的
    绘制流程 :

    - (void)modeUIBezierPath {
        // 开启一个与屏幕大小一样的图形上下文
        UIGraphicsBeginImageContext(self.view.bounds.size);
        UIBezierPath *path = [UIBezierPath bezierPath];
        [path appendPath:[UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 20, 20)]];
        [path appendPath:[UIBezierPath bezierPathWithOvalInRect:CGRectMake(80, 0, 20, 20)]];
        [path moveToPoint:CGPointMake(100, 50)];
        // 注意这里 clockwise 参数是 YES 而不是 NO,如果是 Quartz,需要考虑Y轴翻转的问题传 NO
        [path addArcWithCenter:CGPointMake(50, 50) radius:50 startAngle:0 endAngle:M_PI clockwise:YES];
        // 可以使用 applyTransform 函数来转移坐标的 Transform
        [path applyTransform:CGAffineTransformMakeTranslation(150, 200)];
        [[UIColor redColor] setStroke];
        [path setLineWidth:2];
        [path stroke];
        
        // 从 Context 中获取图像,并显示在界面上
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        UIImageView *imgView = [[UIImageView alloc] initWithImage:image];
        imgView.backgroundColor = [UIColor blackColor];
        [self.view addSubview:imgView];
    }
    

    效果 :


    效果图

    2 - CGContextRef 方式 :

    - (void)modeCGContextRef {
        // 开启一个与屏幕大小一样的图形上下文
        UIGraphicsBeginImageContext(self.view.bounds.size);
        // 获取当前 CGContextRef
        CGContextRef gc = UIGraphicsGetCurrentContext();
        // 可以使用 CGContextTranslateCTM 函数来转移坐标的 Transform
        CGContextTranslateCTM(gc, 150, 200);
        CGContextAddEllipseInRect(gc, CGRectMake(0, 0, 20, 20));
        CGContextAddEllipseInRect(gc, CGRectMake(80, 0, 20, 20));
        CGContextMoveToPoint(gc, 100, 50);
        CGContextAddArc(gc, 50, 50, 50, 0, M_PI, NO);
        [[UIColor redColor] setStroke];
        CGContextSetLineWidth(gc, 2);
        CGContextStrokePath(gc);
        
        // 从 Context 中获取图像,并显示在界面上
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        UIImageView *imgView = [[UIImageView alloc] initWithImage:image];
        imgView.backgroundColor = [UIColor blackColor];
        [self.view addSubview:imgView];
    }
    

    效果 :


    效果图

    3 - CGPath 方式 :

    - (void)modeCGPath {
        // 开始图像绘图
        UIGraphicsBeginImageContext(self.view.bounds.size);
        // 获取当前 CGContextRef
        CGContextRef gc = UIGraphicsGetCurrentContext();
        // 可以使用 CGAffineTransformMakeTranslation 函数来转移坐标的 Transform
        CGAffineTransform transform = CGAffineTransformMakeTranslation(150, 200);
        CGMutablePathRef path = CGPathCreateMutable();
        CGPathAddEllipseInRect(path, &transform, CGRectMake(0, 0, 20, 20));
        CGPathAddEllipseInRect(path, &transform, CGRectMake(80, 0, 20, 20));
        CGPathMoveToPoint(path, &transform, 100, 50);
        CGPathAddArc(path, &transform, 50, 50, 50, 0, M_PI, NO);
        // 将 CGMutablePathRef 添加到当前 Context 内
        CGContextAddPath(gc, path);
        [[UIColor redColor] setStroke];
        CGContextSetLineWidth(gc, 2);
        CGContextStrokePath(gc);
        
        // 从 Context 中获取图像,并显示在界面上
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        UIImageView *imgView = [[UIImageView alloc] initWithImage:image];
        imgView.backgroundColor = [UIColor blackColor];
        [self.view addSubview:imgView];
    }
    

    效果 :


    效果图

    另外 :

    由于三种方式本质上都是一样的
    都是使用Quartz来绘画
    使用中很多地方都是互通的
    比如 CGPath 和 UIBezierPath 的互转

    CGPathRef cgPath = CGPathCreateMutable();
    UIBezierPath *bezierPath = [UIBezierPath bezierPathWithCGPath:cgPath];
    
    UIBezierPath *bezierPath = [UIBezierPath bezierPathWithCGPath:cgPath];
    CGPathRef cgPath = bezierPath.CGPath;
    

    所以上面任何用 CGPath 的地方都可以换成 UIBezierPath
    相反也同理

    相关文章

      网友评论

        本文标题:iOS 三种线的绘制方式 : CGContextRef CG

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