转载自:http://blog.csdn.net/maomaopanjiu/article/details/46900463
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];