Quartz2D
标签(空格分隔): ios进阶
什么是Quartz2D
- Quartz 2D是一个二维绘图引擎,同时支持iOS和Mac系统,Quartz 2D能生成绘制图形、绘制文字、绘制\生成图像、读取\生成PDF、截图\裁剪图片
自定义UI控件 …… - 有些UI界面极其复杂、而且比较个性化,用普通的UI控件无法实现,这时可以利用Quartz2D技术将控件内部的结构画出来,自定义控件的样子,iOS中大部分控件的内容都是通过Quartz2D画出来的,Quartz2D在iOS开发中很重要的一个价值是:自定义view(自定义UI控件)
图形上下文
图形上下文的作用
- 保存绘图信息、绘图状态
- 决定绘制的输出目标(绘制到什么地方去?)
- Quartz2D提供了以下几种类型的Graphics Context:
- Bitmap Graphics Context
- PDF Graphics Context
- Window Graphics Context
- Layer Graphics Context
- Printer Graphics Context
自定义view
自定义view步骤
- 新建一个类,继承自UIView
- 实现
- (void)drawRect:(CGRect)rect
方法
- (在
drawRect:
方法中才能取得跟view相关联的图形上下文) - 系统在调用drawRect方法,会自动帮你创建一根跟view相关联的上下文,并且传递给你
- 调用view的
setNeedsDisplay
或者setNeedsDisplayInRect:
时系统会调用该方法
- (在
- 在
- (void)drawRect:(CGRect)rect
方法中取得跟当前view相关联的图形上下文 - 绘制相应的图形内容
- 利用图形上下文将绘制的所有内容渲染显示到view上面
- (void)drawRect:(CGRect)rect {
// 1.获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 2.拼接路径
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(10, 125)];
[path addQuadCurveToPoint:CGPointMake(240, 125) controlPoint:CGPointMake(125, 0)];
//设置属性
path.lineWidth = 20;
[[UIColor redColor]set];
// 3.路径添加到上下文
CGContextAddPath(ctx, path.CGPath);
// 4.渲染上下文
//CGContextFillPath(ctx);
CGContextStrokePath(ctx);
##常用拼接路径函数
- 新建一个起点
void CGContextMoveToPoint(CGContextRef c, CGFloat x, CGFloat y)
- 添加新的线段到某个点
void CGContextAddLineToPoint(CGContextRef c, CGFloat x, CGFloat y)
- 添加一个矩形
void CGContextAddRect(CGContextRef c, CGRect rect)
- 添加一个椭圆
void CGContextAddEllipseInRect(CGContextRef context, CGRect rect)
- 添加一个圆弧
void CGContextAddArc(CGContextRef c, CGFloat x, CGFloat y,
CGFloat radius, CGFloat startAngle, CGFloat endAngle, int clockwise)
##常用绘制路径函数
- Mode参数决定绘制的模式
void CGContextDrawPath(CGContextRef c, CGPathDrawingMode mode)
- 绘制空心路径
void CGContextStrokePath(CGContextRef c)
- 绘制实心路径
void CGContextFillPath(CGContextRef c)
矩阵操作
- 注意点:必须要在添加路径之前进行形变
利用矩阵操作,能让绘制到上下文中的所有路径一起发生变化
缩放
void CGContextScaleCTM(CGContextRef c, CGFloat sx, CGFloat sy)
旋转
void CGContextRotateCTM(CGContextRef c, CGFloat angle)
平移
void CGContextTranslateCTM(CGContextRef c, CGFloat tx, CGFloat ty)
图形上下文栈
将当前的上下文copy一份,保存到栈顶(那个栈叫做”图形上下文栈”)
void CGContextSaveGState(CGContextRef c)
将栈顶的上下文出栈,替换掉当前的上下文
void CGContextRestoreGState(CGContextRef c)
图片水印
- 由于需要最后得到一张图片而不是在屏幕上显示,所以用
Bitmap Graphics Context
图片上下文,这样就不能在- (void)drawRect:(CGRect)rect
方法中获取上下文,需要自己开启,使用结束后也需要自己结束 核心代码
开启一个基于位图的图形上下文
void UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale)
从上下文中取得图片(UIImage)
UIImage* UIGraphicsGetImageFromCurrentImageContext();
结束基于位图的图形上下文
void UIGraphicsEndImageContext();
代码示例
UIImage *image = [UIImage imageNamed:@"图片"];
// 创建位图上下文
// size:上下文尺寸
// opaque:不透明 Yes 不透明 透明 NO
// scale:是否缩放上下文,0表示不要缩放
UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
[image drawAtPoint:CGPointZero];
// 文字
NSString *str = @"文字";
//文字属性
// 描述文字的属性,颜色,字体大小
NSMutableDictionary *attr = [NSMutableDictionary dictionary];
// 字体
attr[NSFontAttributeName] = [UIFont systemFontOfSize:50];
// 颜色
attr[NSForegroundColorAttributeName] = [UIColor redColor];
// 边框颜色
attr[NSStrokeColorAttributeName] = [UIColor redColor];
// 边框宽度
attr[NSStrokeWidthAttributeName] = @1;
//文字阴影
NSShadow *shadow = [[NSShadow alloc] init];
shadow.shadowOffset = CGSizeMake(3, 3);
shadow.shadowColor = [UIColor yellowColor];
shadow.shadowBlurRadius = 3;
attr[NSShadowAttributeName] = shadow;
[str drawAtPoint:CGPointMake(0, 0) withAttributes:nil];
// 根据上下文的内容生成一张图片
image = UIGraphicsGetImageFromCurrentImageContext();
// 关闭上下文
UIGraphicsEndImageContext();
// 用来网络中传输图片
NSData *data = UIImagePNGRepresentation(image);
[data writeToFile:@"/Users/apple/Desktop/image.png" atomically:YES];
图片裁剪
void CGContextClip(CGContextRef c)
- 将当前上下所绘制的路径裁剪出来(超出这个裁剪区域的都不能显示)
知识点补充
CADisplayLink
- 使用代码
//每次屏幕刷新的时候就会触发,通常我们的屏幕一秒刷新60次,
//注意:调用setNeedsDisplay并不会马上触发drawRect方法,仅仅是给当前这个view设置一个重新绘制的标志,等下一次屏幕刷新的时候才会去调用drawRect
CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(setNeedsDisplay)];
[link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];