iOS开发-Quartz 2D简介(二)

2018-02-08  本文已影响0人  iOS_ZZ

今天给同学们全面的讲解Quartz2D以及Quartz2D的相关实战例子:例子请参考我个人CSDN之前所发的有关Quartz2D的项目的博文,那么废话不多说,直接上代码~

http://blog.csdn.net/ZZ_IOSdeveloper

Quartz2D简介

Quartz2D能完成的工作

Quartz2D在iOS开发中的价值

Quartz2D必须掌握

drawRect:中取得的上下文

图形上下文

常用拼接路径函数

新建一个起点
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)

提示:一般以CGContextDraw、CGContextStroke、CGContextFill开头的函数,都是用来绘制路径的

图形上下文栈

将当前的上下文copy一份,保存到栈顶(那个栈叫做”图形上下文栈”)
void CGContextSaveGState(CGContextRef c)

将栈顶的上下文出栈,替换掉当前的上下文
void CGContextRestoreGState(CGContextRef c)

Quartz2D绘图演练

画线

1> 获取图形上下文
CG:表示这个类在CoreGraphics框架里 Ref:引用目前学的上下文都跟UIGraphics有关,想获取图形上下文,首先敲UIGraphics。
2> 拼接路径:一般开发中用贝塞尔路径,里面封装了很多东西,可以帮我画一些基本的线段,矩形,圆等等。
* 创建贝塞尔路径
* 起点:moveToPoint
* 终点:addLineToPoint
3> 把路径添加到上下文
CGPath转换:UIKit框架转CoreGraphics直接CGPath就能转
4> 把上下文渲染到视图,图形上下文本身不具备显示功能。
* 首先获取图形上下文,然后描述路径,把路径添加到上下文,渲染到视图,图形上下文相当于一个内存缓存区,在内存里面操作是最快的,比直接在界面操作快多了。
5> 在添加一根线
直接addLineToPoint,因为路径是拼接的,默认下一条线的起点是上一条线的终点。
6> 画两跟不连接的线
* 第二次画的时候,重新设置起点,然后画线。一个路径可以包含多条线段。
* 新创建一个路径,添加到上下文。开发中建议使用这种,比较容易控制每根线。
7> 设置绘图状态
* 线段怎么加粗。
* 绘图状态调用顺序:只要在渲染之前就好了,在渲染的时候才会去看绘图的最终状态。
8> 画曲线
* 分析:3个点,起点,终点,控制点。

绘制图形

triangle三角形
1> 关闭路径closePath:从路径的终点连接到起点
2> 填充路径CGContextFillPath:有了封闭的路径就能填充。
3> 设置填充颜色 [[UIColor blueColor] setFill];
4> 设置描边颜色 [[UIColor redColor] setStroke];
5> 不显示描边颜色,为什么?没有设置线宽
6> 设置线宽,还是不显示,为什么?因为绘制路径不对。
7> 即填充又描边CGContextDrawPath:kCGPathFillStroke。

rectangle矩形
circle圆:为什么传入矩形,因为圆内切与矩形
arc圆弧
1> 圆弧属于圆的一部分,因此先要有圆,才有弧。
2> 圆需要起点吗?画线需要,圆也不另外。
3> 起点在哪? 圆心右边
4> 画圆弧还需要起始角度,结束角度,方向,角度必须是弧度

Quarter 1/4圆
画个1/4圆弧,Stroke
填充路径,Fill
必须有封闭路径才能填充,没有封闭路径,系统会自动关闭路径,再去填充
画线连接圆心,自动关闭路径。

基本图形绘制

绘制线段(Line):绘制直线->在添加一条直线->绘制两条直线(路径填充、设置路径属性,颜色,线宽等)->曲线->分析
绘制图形(Shape):绘制三角形(超人内裤)->矩形->圆->圆弧->1/4圆

重绘-下载进度条(setNeedsDisplay)

* 分析有几个控件:UISliderView,自定义view用来画图,UILabel
* 分析思路:滑动UISliderView的时候,把UISliderView的值传给自定义view,改变的显示。
* 怎么监听UISliderView,valueChange事件
* 自定义view搞一个属性接收滑动的值
* 接下来先搞label,因为他比较简单,做东西,先从简单的着手。
* 懒加载label,位置居中,文字居中
* label怎么显示?重写progress的set方法,有数据就展示在label上。
* 绘制圆弧,从哪开始画圆弧。
* 每次转多少°? 角度 = 进度 * M_PI * 2
* startAngle = -M_PI_2
* endAngle = -M_PI_2 + 进度 * M_PI * 2
* 不会及时更新视图显示?为什么,因为drawRect只会在视图显示的时候调用一次。
* 怎么重绘?
* 手动调用drawRect方法,不行,因为你自己不能创建上下文,必须系统调用来调用
* setNeedsDisplay:在view上做一个重绘的标记,在下一次绘图的周期来临,就会先创建好上下文,然后自动调用drawRect重绘。

绘制饼图

* 分析 -> 找规律 -> 得出startA,endA,angle的结论
* startA = endA angle = 比例 * 总度数360° endA = startA + angle
* angle = 自己 / 100.0 * 360
* 一个一个扇形画

绘制柱状图

* 分析 -> 找规律 -> 得出w,h,y,x的结论
* w = viewW / (2 * count - 1)
* h = viewH * 比例

UIKit封装绘图方法演练(不需要上下文)

有时候,在手机客户端app中也需要用到水印技术

比如,用户拍完照片后,可以在照片上打个水印,标识这个图片是属于哪个用户的

实现方式:利用Quartz2D,将水印(文字、LOGO)画到图片的右下角

核心代码
开启一个基于位图的图形上下文
void UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale)

从上下文中取得图片(UIImage)
UIImage * UIGraphicsGetImageFromCurrentImageContext();

结束基于位图的图形上下文
void UIGraphicsEndImageContext();
核心代码
void CGContextClip(CGContextRef c)
将当前上下所绘制的路径裁剪出来(超出这个裁剪区域的都不能显示)
核心代码
- (void)renderInContext:(CGContextRef)ctx;
调用某个view的layer的renderInContext:方法即可

矩阵操作

利用矩阵操作,能让绘制到上下文中的所有路径一起发生变化
缩放
void CGContextScaleCTM(CGContextRef c, CGFloat sx, CGFloat sy)

旋转
void CGContextRotateCTM(CGContextRef c, CGFloat angle)

平移
void CGContextTranslateCTM(CGContextRef c, CGFloat tx, CGFloat ty)

手势解锁

tolcols = 3
计算row,col 按钮的x,y跟col,row有关系,col = i % tolcol row = i / tolcol
计算边距 margin = (view.bounds.size.width - tolcol * btnW) / (tolcol + 1)
btnX = margin + (btnW + margin) * col
btnY = (btnW + margin) * row

Quartz2D的内存管理

使用含有“Create”或“Copy”的函数创建的对象,使用完后必须释放,否则将导致内存泄露

使用不含有“Create”或“Copy”的函数获取的对象,则不需要释放

如果retain了一个对象,不再使用时,需要将其release掉

可以使用Quartz 2D的函数来指定retain和release一个对象。例如,如果创建了一个CGColorSpace对象,则使用函数CGColorSpaceRetain和CGColorSpaceRelease来retain和release对象。

也可以使用Core Foundation的CFRetain和CFRelease。注意不能传递NULL值给这些函数
上一篇下一篇

猜你喜欢

热点阅读