前言
绘图涉及到的知识点:
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绘图的基本步骤:
未完待续。。。。。