美文网首页
iOS开发笔记之绘图

iOS开发笔记之绘图

作者: Veness_ | 来源:发表于2017-04-14 23:37 被阅读285次

    前言

    绘图涉及到的知识点:

    Quartz2D
    ----DrawRect
    CALayer
    ----CAShapeLayer
    UIBezierPath
    

    绘图的方式:

    1、通过Quartz2D框架,自定义view,实现view的drawRect方法就可以画出一些想要的图形。
    2、使用CAShapeLayer与UIBezierPath可以实现不在view的drawRect方法中就画出一些想要的图形。
    3、其他(暂时不讲)

    概念解析

    1、Quartz2D

    提到iOS中的绘图,必然会想到Quartz2D,Quzrtz2D是一个二维绘图引擎,支持iOS和Mac系统。Quartz2D的API来源于CoreGraphics框架。

    2、CAShapeLayer

    CAShapeLayer继承与CALayer,因此,可使用CALayer的所有属性。但是CAShapeLayer需要和贝塞尔曲线(UIBezierPath)配合才有意义

    主要属性:
    // CAShapeLayer 绘制的路径
    @property(nullable) CGPathRef path;
    //路径中的填充颜色
    @property(nullable) CGColorRef fillColor;
    //填充规则
    @property(copy) NSString *fillRule;
    //画笔颜色(路径的颜色,边框颜色)
    @property(nullable) CGColorRef strokeColor;
    //这是一组范围值,路径绘制开始和结束的范围(0 -> 1)
    @property CGFloat strokeStart;
    @property CGFloat strokeEnd;
    //设置虚线显示的起点距离,设置为8,则显示长度8之后的线
    @property CGFloat lineDashPhase;
    //设置虚线线段的长度和空格的长度,@[@20,@30,@40,@50],画20空30画40空50
    @property(nullable, copy) NSArray
    

    ** CAShapeLayer与drawRect的比较:**
    1、drawRect属于CoreGraphics框架,占用CPU,性能消耗大;
    2、CAShapeLayer属于CoreAnimation框架,通过GPU来渲染图形,节省性能;动画渲染直接提交给GPU,不消化内存;
    **1、温馨提示:drawRect只是一个方法而已,是UIView的方法,重写此方法可以完成绘图功能
    2、CAShapeLayer动画仅仅限于沿着边缘的动画效果,它实现不了填充效果 **

    3、UIBezierPath

    UIBezierPath是在UIKit中的一个类,继承于NSObject,可以创建矢量路径,此类是CoreGraphics框架关于path的一个OC封装。所以本质两者相同,只是UIBezierPath更加好用

    + (instancetype)bezierPath;
    + (instancetype)bezierPathWithRect:(CGRect)rect;
    + (instancetype)bezierPathWithOvalInRect:(CGRect)rect;
    + (instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius; // rounds all corners with the same horizontal and vertical radius
    + (instancetype)bezierPathWithRoundedRect:(CGRect)rect byRoundingCorners:(UIRectCorner)corners cornerRadii:(CGSize)cornerRadii;
    + (instancetype)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise;
    + (instancetype)bezierPathWithCGPath:(CGPathRef)CGPath;
    
    CAShapeLayer与UIBezierPath的关系:
    • 1、CAShapeLayer中的shape代表形状的意思,所以要形状才能生效
    • 2、贝塞尔曲线(UIBezierPath)创建矢量路径,UIBezierPath雷士多CGPathRef的封装;
    • 3、贝塞尔曲线(UIBezierPath)提供路径,CAShapeLayer在提供的路径中进行渲染,路径闭环,所以绘制出了shape;
    • 4、用于CAShapeLayer的贝塞尔曲线一定是闭环,即使贝塞尔曲线(UIBezierPath)不是一个闭环的曲线

    Quartz2D能完成的工作:

    • 绘制图形:线条、三角形、矩形、弧形等等
    • 绘制文字
    • 绘制/生成图片
    • 读取和生成PDF
    • 截图裁剪图片
    • 自定义UI控件

    CAShapeLayer能完成的工作:

    使用CAShapeLayer(属于CoreAnimation)与贝塞尔曲线可以实现不在view的drawRect(继承于CoreGraphics走的是CPU,消耗的性能较大)方法中画出一些想要的图形

    绘图的基本步骤:

    //绘制直线
    - (void)drawRect:(CGRect)rect
    {
        // 1.取得和当前视图相关联的图形上下文(因为图形上下文决定绘制的输出目标)/
        
        // 如果是在drawRect方法中调用UIGraphicsGetCurrentContext方法获取出来的就是Layer的上下文
        CGContextRef ctx = UIGraphicsGetCurrentContext();
        
        // 2、设置绘图状态
        
        // 设置线条颜色 红色
        CGContextSetRGBStrokeColor(ctx, 1.0, 0, 0, 1.0);
        // 设置线条宽度
        CGContextSetLineWidth(ctx, 10);
        // 设置线条的起点和终点的样式
        CGContextSetLineCap(ctx, kCGLineCapRound);
        // 设置线条的转角的样式
        CGContextSetLineJoin(ctx, kCGLineJoinRound);
        
        // 3.拼接路径绘图(绘制直线)
        
        // 设置起点
        CGContextMoveToPoint(ctx, 10, 10);
        // 设置终点
        CGContextAddLineToPoint(ctx, rect.size.width - 10, 10);
        
        //3、保存绘图信息(渲染)
        
        // 绘制一条空心的线
        CGContextStrokePath(ctx);
    
    }
    

    生成水印图:

    + (instancetype)imageWithBackgroundImageName:(NSString *)bgName log:(NSString *)logNmae
    {
        // 0. 加载背景图片
        UIImage *image = [UIImage imageNamed:bgName];
        
        // 1.创建bitmap上下文
        // 执行完这一行在内存中就相遇创建了一个UIImage
        UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
        
        // 2.绘图图片
        // 绘制背景图片
        [image drawAtPoint:CGPointMake(0, 0)];
        
        // 绘制水印'
        
         UIImage *logImage = [UIImage imageNamed:logNmae];
         
         CGFloat margin = 10;
         CGFloat logY = margin;
         CGFloat logX = image.size.width - margin - logImage.size.width;
         [logImage drawAtPoint:CGPointMake(logX, logY)];
        
        
    //    NSString *str = @"哈哈哈";
    //    [str drawAtPoint:CGPointMake(150, 50) withAttributes:nil];
        
        // 3.获得图片
        UIImage *newImage =  UIGraphicsGetImageFromCurrentImageContext();
        
        return newImage;
    }
    

    截图裁剪图片:

    
    

    CAShapeLayer结合UIBezierPath绘图的基本步骤:

    未完待续。。。。。

    相关文章

      网友评论

          本文标题:iOS开发笔记之绘图

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