Quartz 2D 在 swift 中的使用

Quartz 2D是一个二维绘图引擎,同时支持iOS和Mac系统。
其实 iOS 中很多控件都是通过 Quartz 2D 画出来的.
同时Quartz 2D还可以做这些事情,

1、剪裁图形
2、涂鸦/画板(如签名等)
3、手势解锁(连线)
4、折线图、饼状图、柱形图等绘制(虽然我都是直接用 charts)

使用 Quartz 2D绘图的核心步骤:

1、获得上下文
2、绘制/拼接绘图路径
3、将路径添加到上下文
4、渲染上下文
记住:所有的绘图,都是这个步骤,即使使用贝塞尔路径,也只是对这个步骤进行了封装。
对于绘图而言,拿到上下文很关键。

其中图形上下文有五种


WechatIMG2009.jpeg
Bitmap Graphics Context
PDF Graphics Context
Window Graphics Context
Layer Graphics Context
Printer Graphics Context

使用Quartz 2D自定义 UI 控件绘图的方法

1.新建一个类,继承自UIView
2.必须实现- (void)drawRect:(CGRect)rect方法,然后在这个方法中,可以:
取得跟当前view相关联的图形上下文
绘制相应的图形内容,绘制时产生的线条称为路径。 路径由一个或多个直线段或曲线段组成。
利用图形上下文将绘制的所有内容渲染显示到view上面
也可以:
利用UIKit封装的绘图函数直接绘图

关于drawRect:

为什么要实现drawRect:方法才能绘图到view上?
因为在drawRect:方法中才能取得跟view相关联的图形上下文
 
drawRect:方法在什么时候被调用?
当view第一次显示到屏幕上时(被加到UIWindow上显示出来)
调用view的setNeedsDisplay或者setNeedsDisplayInRect:时

在drawRect:方法中取得上下文后,就可以绘制东西到view上
 
View内部有个layer(图层)属性,drawRect:方法中取得的是一个Layer Graphics Context,因此,绘制的东西其实是绘制到view的layer上去了
 
View之所以能显示东西,完全是因为它内部的layer
    //一些常用方法
    //获取上下文对象
    let context = UIGraphicsGetCurrentContext()
    
    //线条颜色
    context?.setStrokeColor(UIColor.red.cgColor)
    
    //线条宽度
    context?.setLineWidth(1.0)
    
    //移动画笔到某一点
    context?.move(to: CGPoint(x: 10, y: 10))
    
    //画线
    context?.addLine(to: CGPoint(x: gameSize , y: 10))
    
    //画弧线 (方法1 ,这个方法如果画一个完整的圆的话,
    //有起始点的时候,只会连接起始点和重点,不会出现圆的轨迹!)
    context?.addArc(center: CGPoint.init(x: 150, y: 100), radius: 30, startAngle: 0, endAngle: CGFloat(M_PI*2), clockwise: true);
使用这个方法画完整圆.jpeg
context?.addArc(center: CGPoint.init(x: 150, y: 100), radius: 30, startAngle: 0, endAngle: CGFloat(M_PI), clockwise: true);
如果弧度为180度就没有这个问题.jpeg
    //画圆弧 (方法2)
    context?.addArc(tangent1End: CGPoint(x: 50, y: 50), tangent2End: CGPoint(x: 100, y: 50), radius: 50)


    //二次贝塞尔曲线
    context?.addQuadCurve(to: CGPoint.init(x: 150, y: 150), control: CGPoint.init(x: 50, y: 100))
    
    //三次贝塞尔曲线
    context?.addCurve(to: CGPoint.init(x: 250, y: 150), control1: CGPoint.init(x: 50, y: 100), control2: CGPoint.init(x: 100, y: 150))
    
    //设置填充颜色
    context?.setFillColor(UIColor.brown.cgColor);
    //绘制矩形
    context?.fill(CGRect.init(x: 50, y: 50, width: 100, height: 50));
    
    //绘制椭圆
    context?.strokeEllipse(in: CGRect.init(x: 50, y: 50, width: 100, height: 50));

    //旋转
    context?.rotate(by: CGFloat.pi * 0.3)
        
    //如果是需要使用矩阵变换(如平移,缩放,旋转等),需要把添加路径放到后面
    //也就是需要把路径添加进加入上下文之前进行,
    context?.addArc(center: CGPoint(x: 50, y: 50), radius: 50, startAngle: 0, endAngle: CGFloat.pi, clockwise: true)
    
    //绘制
    context?.drawPath(using: .stroke)

上下文栈

1.入栈context?.saveGState()
2.出栈context?.restoreGState()
3.如果出战的次数大于入栈,就会奔溃
4.什么是入栈?就是拷贝当前图形上下文,然后放到栈中, 只使用一个CGContextRef的话,需要很多修改上下文属性(颜色,线宽等)的重复代码,所以可以保存当前上下文属性进入栈中
5.如何理解拷贝图形上下文,我们操作的图形上下文成为A,此时如果图形上下文就设置了context?.setStrokeColor(UIColor.green.cgColor)这一个属性,入栈(我们把拷贝后入栈的成为B),然后我们继续操作当前上下文(现在称为 B),但是我们出栈 A, 当前上下文的样式都是只有一个context?.setStrokeColor(UIColor.green.cgColor)的状态!说白了,就是保存某种图形上下文的状态!
5.出栈的上下文,将样式赋值给当前样式,然后释放

出栈入栈参考自 王鑫20111
https://www.jianshu.com/p/604b386d0468

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,366评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,521评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,689评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,925评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,942评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,727评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,447评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,349评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,820评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,990评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,127评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,812评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,471评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,017评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,142评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,388评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,066评论 2 355

推荐阅读更多精彩内容

  • --绘图与滤镜全面解析 概述 在iOS中可以很容易的开发出绚丽的界面效果,一方面得益于成功系统的设计,另一方面得益...
    韩七夏阅读 2,731评论 2 10
  • 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥ios动画全貌。在这里你可以看...
    每天刷两次牙阅读 8,497评论 6 30
  • Medium这题真是,一开始看答案都看不懂, 听讲解也听不懂. 后来玩了一会儿回来看答案发现突然明白了. 基本上是...
    greatseniorsde阅读 813评论 1 1
  • 自从来到大学,我对你思念仍像以前,但没有那丝伤感。因为我想通了,我要等,等你归来,归来我身边。最近一天天过去,如同...
    冀DWJ421阅读 215评论 0 0
  • 上午去海沧项目打酱油,下午又去晋江买衣服,晚上陪领导去吃饭,结束后去万达遛弯。看似一天也是不亦乐乎,晚上发现...
    aweness阅读 167评论 0 0