Quartz2D

Quartz2D是支持iOS和Mac系统的二维绘制引擎,它可以绘制:

  • 绘制图形(图形,线条,圆等)
  • 绘制文字
  • 绘制/生成图片
  • 读取/生成PDF
  • 截图

Quartz2D主要功能就是以画为主,它可以实现与用户交互的画板或实现UIKit框架中不好展示的一些图形 如:饼图,柱状图。在自定义控件的时候也可以绘制控件,iOS中大部分控件都是用Quartz2D绘制出来的。

图形上下文

图形上下文说白了就是画布,没有图形上下文就不能绘制任何图形,Quartz2D 提供了五种图形上下文,不同的图形上下文决定画出的内容将展示在不同的情况中。

  • Bitmap Graphics Context:位图上下文,在这个上下文中绘制的内容可以获取成图片。(这个上下文只能主动创建来使用,使用完毕后要销毁)。
  • PDF Graphics Context:PDF上下文,用于生成绘制PDF文件。
  • Window Graphics Context:
  • Layer Graphics Context:图层上下文,一般用于绘制UI控件使用。
  • Printer Graphics Context:

drawRect方法

一般我们最常用的就是绘制一些自定义控件,那么如何获得相应上下文呢?答案是:在drawRect方法中获取,一般获取到的是Layer Graphics Context(图层上下文),获取到上下文后就可以绘制一些我们想要的内容了,需要注意的是我们绘制的内容全部在view内部的layer上。

class CustomView: UIView {
override func drawRect(rect: CGRect) {
// 获取当前的上下文
let contextRef = UIGraphicsGetCurrentContext()
}
}

那么这个方法什么时候被调用?请看以下几种情况:

当view第一次显示在屏幕上时。

改变某个属性让view必须重绘时(比如改变背景色,添加子view时)。

当我们主动调用setNeedsDisplay或setNeedsDisplayInRect方法时drawRect会被调用,注意:我们主动调用drawRect方法是无效的。

绘制一条简单的线

class CustomView: UIView {
override func drawRect(rect: CGRect) {
// 获取当前的上下文
let contextRef = UIGraphicsGetCurrentContext()
CGContextMoveToPoint(contextRef, 0, 0)
CGContextAddLineToPoint(contextRef, 50, 50)
CGContextSetLineWidth(contextRef, 20)
UIColor.yellowColor().set()
CGContextStrokePath(contextRef)
}
}

下面我们来看下常用的绘制函数(更多属性参考官方文档):

  • UIGraphicsGetCurrentContext():获取当前的上下文,一般在drawRect方法中才能获得。
  • CGContextMoveToPoint(contextRef, 50, 0.0):新建一个起点。
  • CGContextAddLineToPoint(contextRef, 50, 50):新添加一条线到新的点。
  • CGContextAddLines(contextRef, [CGPointMake(10.0, 10.0), CGPointMake(50.0, 50.0), CGPointMake(20.0, 80.0)], 3):添加若干条线
  • CGContextAddRect(contextRef, CGRectMake(10, 10, 20, 20)):添加一个矩形。
  • CGContextAddEllipseInRect(contextRef, CGRectMake(10, 10, 60, 60)):添加一个椭圆。
  • CGContextAddArc(contextRef, 40, 40, 20, 0.0, CGFloat(M_PI), 0):添加一条圆弧,解释下几个参数:1图层上下文,2圆心的X点,3圆心的Y点,4半径长度,5起始角度,6结束角度,7是否是顺时针 1为顺时针 0为逆时针。
  • CGContextAddArcToPoint(contextRef, 40.0, 40.0, 70.0, 80.0, 30.0):添加一条曲线。
  • CGContextClosePath(contextRef):将没有结合的两个点封起来。
  • CGContextDrawPath(contextRef, .FillStroke):绘制图形,并且设置填充模式。
  • CGContextStrokePath(contextRef):绘制图形,只是绘制不会有填充封闭效果。
  • CGContextFillPath(contextRef):绘制图形,会有填充封闭效果。
  • CGContextRotateCTM(contextRef, CGFloat(M_PI_4)):矩阵旋转。
  • CGContextScaleCTM(contextRef, 1.0, 0.5):矩阵缩放。
  • CGContextTranslateCTM(contextRef, 10, 10):矩阵平移。

上下文栈

先来看两个方法:

  • CGContextSaveGState(contextRef):将当前的上下文copy一份,保存到上下文栈的栈顶。
  • CGContextRestoreGState(contextRef):将上下文栈栈顶重置。

那么上下文栈有什么用呢?下面来看一个比较繁琐的例子:

    override func drawRect(rect: CGRect) {
// 获取当前的上下文
let contextRef = UIGraphicsGetCurrentContext() // 设置上下文的状态
CGContextSetLineWidth(contextRef, 3.0)
CGContextSetLineCap(contextRef, .Round)
UIColor.redColor().set() // 绘制第一条线
CGContextMoveToPoint(contextRef, 0.0, 0.0)
CGContextAddLineToPoint(contextRef, 30.0, 30.0) // 绘制
CGContextStrokePath(contextRef) // 重置属性
CGContextSetLineCap(contextRef, .Square)
CGContextSetLineWidth(contextRef, 1.0)
UIColor.blackColor().set() // 绘制第二条线
CGContextMoveToPoint(contextRef, 10.0, 50.0)
CGContextAddLineToPoint(contextRef, 80.0, 80.0)
// 绘制
CGContextStrokePath(contextRef)
}

分析:

  1. 我们绘制第一条线之前把上下文的属性做了设置,之后绘制。
  2. 如果第二条线不想与第一条线一样,做了属性的再一次设置成默认的样式,然后绘制。

注意:虽然这样也可以达成效果,but 如果在实际开发中会大大增加代码量,最好的办法是重置栈顶的上下文。

看一个正确做法的例子:

    override func drawRect(rect: CGRect) {
// 获取当前的上下文
let contextRef = UIGraphicsGetCurrentContext() // 1、copy上下文至栈顶
CGContextSaveGState(contextRef) // 设置状态 再次copy
CGContextSetLineWidth(contextRef, 3.0)
CGContextSaveGState(contextRef) // 设置上下文的状态
CGContextSetLineCap(contextRef, .Round)
UIColor.redColor().set() // 绘制第一条线
CGContextMoveToPoint(contextRef, 0.0, 0.0)
CGContextAddLineToPoint(contextRef, 30.0, 30.0)
CGContextStrokePath(contextRef) // 2、将栈顶出栈,重置当前的上下文
CGContextRestoreGState(contextRef) // 绘制第二条线
CGContextMoveToPoint(contextRef, 10.0, 50.0)
CGContextAddLineToPoint(contextRef, 80.0, 80.0)
CGContextStrokePath(contextRef) // 3、再次出栈
CGContextRestoreGState(contextRef) // 绘制第三条线
CGContextMoveToPoint(contextRef, 40.0, 40.0)
CGContextAddLineToPoint(contextRef, 90.0, 70.0)
CGContextStrokePath(contextRef)
}
  • 第一条线:圆角,颜色为红色,宽度为3
  • 第二条线:当绘制完第一条线完毕后做了一次出栈,第二条线样式为 宽度为3 其他默认。
  • 第三条线:当绘制完第二条线后又做了一次出栈,第三条线为默认样式。

Quartz2D 备忘 + 学习的更多相关文章

  1. JavaScript 教程学习进度备忘(二)

    备忘:之前,只将“JS 教程”学习完毕,这篇记录:“JS HTML DOM ”.“JS 对象”.“JS Window”.“JS 库” 书签:跳过:另外跳过的内容有待跟进 _______________ ...

  2. 个人 WPF+EF(DBFirst) 简单应用开发习惯及EF学习测试(备忘) -- 2

    接上篇:个人 WPF+EF(DBFirst) 简单应用开发习惯及EF学习测试(备忘) -- 1 Step1 在主程序中设置连接数据库 从Model类库的 App.Config 把数据库字符串拷贝出来, ...

  3. sqlserver -- 学习笔记(一)自定义函数(学习总结,备忘)

    SQL Server自定义函数,以前只在书上看过,没有动手去敲一敲,今天刚好接触到,看了几篇博文学习了下.做好备忘很重要!! (@_@)Y Learn from:http://www.cnblogs. ...

  4. Android学习备忘笺01Activity

    01.设置视图 在Android Studio新建的项目中,通过 setContentView(R.layout.activity_main);方法将res/layout/activity_main. ...

  5. 工作效率-十五分钟让你快速学习Markdown语法到精通排版实践备忘

    关注「WeiyiGeek」公众号 设为「特别关注」每天带你玩转网络安全运维.应用开发.物联网IOT学习! 希望各位看友[关注.点赞.评论.收藏.投币],助力每一个梦想. 文章目录: 0x00 前言简述 ...

  6. leaflet 学习备忘

    leaflet 开源js地图工具.非常好用. leaflet参考:http://leafletjs.com/ 特性: 完全开源,可以基于不同的第三方瓦片生成地图. 基于原始GPS,无需转换 可创建离线 ...

  7. SSO之CAS备忘

    http://blog.chinaunix.net/uid-28380443-id-4740103.html 自己负责的公司基于CAS单点登录平台架构已经上线运行,很多细节的东西是时候备忘一下了,开源 ...

  8. Haxe UI框架StablexUI的使用备忘与心得(序)

    最近在手上的项目开发中,从原来的使用Sprite全手写UI,开始逐步使用StablexUI,感觉还是相当不错的,强大.高效.轻量.灵活,非常适应我当前的实际需求. 不过作为小种语言的一个小众第三方开源 ...

  9. [CSS3备忘] transform animation 等

    一些CSS不经常用就会忘记,好吧,现在整理再学习一下,也留做备忘,方便以后查看... perspective的理解: 1.数值越小,用户与3D空间Z平面距离越近,视觉效果更令人印象深刻(比如看电影,越 ...

随机推荐

  1. c++ 数据持久层研究(一)

    C++ORM框架自动生成代码数据库  用过Java的都知道SSH框架,特别对于数据库开发,Java领域有无数的ORM框架,供数据持久层调用,如Hibernate,iBatis(现在改名叫MyBatis ...

  2. hysdk代码解析

    navigator 1. navigator.userAgent 浏览器的用户代理字符串 2. navigator.platform 浏览器所在的系统平台 window 1. window.devic ...

  3. arcmap10如果判断一个面是否含洞

    使用字段计算器,使用python !Shape.isMultipart!结果为true就是,false不是

  4. ios开发时候,出现A valid provisioning profile for this executable was not found 错误

    今天一大早起来,做ios的开发,发现了一下错误:A valid provisioning profile for this executable was not found 错误的产生是在开发模式下产 ...

  5. 基于DOM的XSS注入漏洞简单解析

    基于DOM的XSS注入漏洞简单解析http://automationqa.com/forum.php?mod=viewthread&tid=2956&fromuid=21

  6. maven项目在tomcat中运行遇到的问题

    在使用maven构建项目,并在tomcat容器中运行的时候遇到了一些问题,现做一下记录 maven项目中jdk版本会自动恢复 maven项目的编译jdk即使在window -> java -&g ...

  7. Linq 与UnitOfWork

    submitchages(linq to sql)或者savechanges(ef)的次数是根据你操作方法的数量决定的,也即是:它只认识自己的提交语句(submtchanges,savechanges ...

  8. Come and join us at English corner

    2012.12.26 Hi all, How are you doing? Merry post-Christmas and happy upcoming New year!! I wish you ...

  9. Tomcat6.0数据库连接池配置

    http://blog.163.com/magicc_love/blog/static/185853662201111101130969/ oracle驱动包Tomcat 6.0配置oracle数据库 ...

  10. 广告系统中weak-and算法原理及编码验证

    wand(weak and)算法基本思路 一般搜索的query比较短,但如果query比较长,如是一段文本,需要搜索相似的文本,这时候一般就需要wand算法,该算法在广告系统中有比较成熟的应 该,主要 ...