iOS开发笔记之绘图

2017-04-14  本文已影响285人  Veness_

前言

绘图涉及到的知识点:

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的关系:

Quartz2D能完成的工作:

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绘图的基本步骤:

未完待续。。。。。

上一篇下一篇

猜你喜欢

热点阅读