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. 获取本地IP和端口号的指令

    ipconfig就可以获取ip 获取端口号的指令: 开始--运行--cmd--输入netstat an(中间有一空格)

  2. (转+整理) oracle authid definer 与 authid current_user

    转:http://blog.csdn.net/indexman/article/details/17067531 http://blog.csdn.net/liqfyiyi/article/detai ...

  3. HINSTANCE数据类型

    作者:马 岩(Furzoom) (http://www.cnblogs.com/furzoom/)版权声明:本文的版权归作者与博客园共同所有.转载时请在明显地方注明本文的详细链接,未经作者同意请不要删 ...

  4. Linux基础命令(三)

    一.常用命令—文件目录类命令 1.ls 列出指定或默认目录的文件信息 使用形式: ls [选项] [目录名] 实例: $ls $ls –als $ls /home/sq/Desktop $ls ./D ...

  5. PHP + ajax 实现异步登录验证

    login.html: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http:/ ...

  6. 第九篇:web之前端之web上传文件的方式

    前端之web上传文件的方式   前端之web上传文件的方式 本节内容 web上传文件方式介绍 form上传文件 原生js实现ajax上传文件 jquery实现ajax上传文件 form+iframe构 ...

  7. Android 绘制动态图

    最近准备技能大赛,需要将从传感器中读出的数据在移动客户端以图的形式绘制出来,因为平时很少绘图,于是各种查资料,算是勉强做出来了. 以下是大赛理论效果图(左)和实际效果图(右),真的是理想很丰满,现实很 ...

  8. 总结一下const和readonly

    const和readonly的值一旦初始化则都不再可以改写: const只能在声明时初始化:readonly既可以在声明时初始化也可以在构造器中初始化: const隐含static,不可以再写stat ...

  9. git github 使用教程

    参考文章:文章地址: http://wuyuans.com/2012/05/github-simple-tutorial/ github是一个基于git的代码托管平台,付费用户可以建私人仓库,我们一般 ...

  10. vmstat,iostat,sar命令详解

    Procs r: 等待运行的进程数 b: 处在非中断睡眠状态的进程数 w: 被交换出去的可运行的进程数.此数由 linux 计算得出,但 linux 并不耗尽交换空间 Memory swpd: 虚拟内 ...