Swift操作Quartz 2D进行简单的绘图与坐标变换的教程

Quartz 2D简介
Quartz 2D是苹果公司开发的一个二维图形绘制引擎,同时支持iOS和Mac系统。

它是一套基于C的API框架,提供了低级别、轻量级、高保真度的2D渲染。它能完成的工作有:

  • 绘制图形 : 线条\三角形\矩形\圆\弧等
  • 绘制文字
  • 绘制\生成图片(图像)
  • 读取\生成PDF
  • 截图\裁剪图片
  • 自定义UI控件

Quartz 2D进行绘图
iOS绘图技术主要有UIKit,Quartz 2D,Core Animation和OpenGL ES。我们平常对UIKit应该不陌生,而Quartz 2D与UIKit的一个区别是:
Quartz 2D的坐标原点在左下角,而UIKit的坐标原点在左上角。
在开始前作下准备工作:创建一个新的Cocoa Touch Class,继承自UIView,然后去StoryBoard把view视图关联下新创建的类。

1.填充和描边
重写绘图方法drawRect(),添加代码:

代码如下:

override func drawRect(rect: CGRect) {
     //填充背景
     UIColor.brownColor().setFill()
     //填充矩形
     UIRectFill(rect)
     UIColor.whiteColor().setStroke()
     //矩形描边
     let frame = CGRectMake(10, 24, 100, 300)
     UIRectFrame(frame)
}

运行效果:

2.绘制三角形
确定三个点就能绘制出三角形,当然其他的图形(如矩形)也是类似。
在drawRect()里添加代码:

代码如下:

override func drawRect(rect: CGRect) {
    let context = UIGraphicsGetCurrentContext()
    //绘制起始点
    CGContextMoveToPoint(context, 120, 104)
    //从起始点到这一点
    CGContextAddLineToPoint(context, 150, 204)
    CGContextAddLineToPoint(context, 200, 104)
    //闭合路径
    CGContextClosePath(context)
    UIColor.blackColor().setStroke()
    UIColor.greenColor().setFill()
    //绘制路径
    CGContextDrawPath(context, CGPathDrawingMode.FillStroke)
}

运行效果:

依此类推,大家可以试试怎么去画长方形,正方形和不规则多边形。

3.绘制图片和文字
首先准备一张图片放入工程中,注意不要放在Assets.xcassets文件夹下,因为这里寻找的路径是在工程文件夹。而如果把图片放在Assets.xcassets文件夹下,就要使用另外的一种方法。
在drawRect()里添加代码:

代码如下:

override func drawRect(rect: CGRect) {
    //绘制图片和文字
    //这种方式添加图片需要把图片放到根目录下,而不是Assets.xcassets下
    let imagePath = NSBundle.mainBundle().pathForResource("头像004", ofType: "jpg")
    let image = UIImage(contentsOfFile: imagePath!)
    //具体位置根据你的图片来调整
    image?.drawInRect(CGRectMake(100,100, 200, 200))
    let title = "头像"
    let font = UIFont.systemFontOfSize(44)
    let attr = [NSFontAttributeName:font]
    title.drawAtPoint(CGPointMake(100, 20), withAttributes: attr)
}

运行效果:

Quartz 2D中的坐标变换
注意:坐标变换操作必须要在添加图形之前,如果设置在添加图形之后的话会无效。

我们先画一个正方形做完参考:

代码如下:

override func drawRect(rect: CGRect) {
    let context = UIGraphicsGetCurrentContext()
    CGContextSetLineWidth(context, 2.0)
    CGContextSetStrokeColorWithColor(context, UIColor.redColor().CGColor)
    let rectangle = CGRectMake(125, 50, 50, 50)
    CGContextAddRect(context, rectangle)
    CGContextStrokePath(context)
}

1、平移
func CGContextTranslateCTM(c: CGContext?, _ tx: CGFloat, _ ty: CGFloat)
该方法相当于把原来位于 (0, 0) 位置的坐标原点平移到 (tx, ty) 点。在平移后的坐标系统上绘制图形时,所有坐标点的 X 坐标都相当于增加了 tx,所有点的 Y 坐标都相当于增加了 ty。

代码如下:

override func drawRect(rect: CGRect) {
    let context = UIGraphicsGetCurrentContext()
    CGContextSetLineWidth(context, 2.0)
    CGContextSetStrokeColorWithColor(context, UIColor.redColor().CGColor)
    CGContextTranslateCTM(context, -50, 25) // 向左向下平移
    let rectangle = CGRectMake(125, 50, 50, 50)
    CGContextAddRect(context, rectangle)
    CGContextStrokePath(context)
}

2、缩放
func CGContextScaleCTM(c: CGContext?, _ sx: CGFloat, _ sy: CGFloat)
该方法控制坐标系统在水平方向和垂直方向上进行缩放。在缩放后的坐标系统上绘制图形时,所有点的 X 坐标都相当于乘以 sx 因子,所有点的 Y 坐标都相当于乘以 sy 因子。

代码如下:

override func drawRect(rect: CGRect) {
    let context = UIGraphicsGetCurrentContext()
    CGContextSetLineWidth(context, 2.0)
    CGContextSetStrokeColorWithColor(context, UIColor.redColor().CGColor)   
    CGContextScaleCTM(context, 0.5, 1)
    let rectangle = CGRectMake(125, 50, 50, 50)
    CGContextAddRect(context, rectangle)
    CGContextStrokePath(context)
}

3、旋转
func CGContextRotateCTM(c: CGContext?, _ angle: CGFloat)
该方法控制坐标系统旋转 angle 弧度。在缩放后的坐标系统上绘制图形时,所有坐标点的 X、Y 坐标都相当于旋转了 angle弧度之后的坐标。

代码如下:

override func drawRect(rect: CGRect) {
    let context = UIGraphicsGetCurrentContext()
    CGContextSetLineWidth(context, 2.0)
    CGContextSetStrokeColorWithColor(context, UIColor.redColor().CGColor)
    CGContextRotateCTM(context, CGFloat(M_PI_4))
    let rectangle = CGRectMake(125, 50, 50, 50)
    CGContextAddRect(context, rectangle)
    CGContextStrokePath(context)
}

注意:旋转的时候,是整个 layer 都旋转了,所以 layer 看起来应该是这样的:

这个时候若想移动 view ,就应该按照这个旋转过的坐标系来移动:

代码如下:

override func drawRect(rect: CGRect) {
    let context = UIGraphicsGetCurrentContext()
    CGContextSetLineWidth(context, 2.0)
    CGContextSetStrokeColorWithColor(context, UIColor.redColor().CGColor)
    CGContextRotateCTM(context, CGFloat(M_PI_4))
    CGContextTranslateCTM(context, 0, -100) // 在新坐标系中向上移动100点,视图上看起来像是向右向上都移动了
    let rectangle = CGRectMake(125, 50, 50, 50)
    CGContextAddRect(context, rectangle)
    CGContextStrokePath(context)
}

(0)

相关推荐

  • Swift自定义iOS中的TabBarController并为其添加动画

    自定义TabBarController 有时候默认的TabBarController不能满足我们的开发需求,比如你想用彩色的图标,系统却只调用图标的轮廓,所以我们需要自己定义一下TabBar. 方法一:修改TabBarController中的TabBar 新建 CustomTabBarController 类继承自 UITabBarController,并在Storyboard中设置: 首先自定义 tabBar 的背景,在 viewDidLoad() 方法中添加: 复制代码 代码如下: // 用

  • 使用Swift实现iOS App中解析XML格式数据的教程

    在IOS中,提供了一套解析XML数据的API.其实也很简单,就是NSXMLParser和NSXMLParserDelegate. 可以直接指定到XML的URL去实例化NSXMLParser 复制代码 代码如下: public convenience init?(contentsOfURL url: NSURL) 解析文件,返回的是一次解析的结果 复制代码 代码如下: NSXMLParser.parse() -> Bool 监听解析节点的属性 复制代码 代码如下: NSXMLParserDeleg

  • Swift实现iOS应用中短信验证码倒计时功能的实例分享

    在开始之前,我们先来了解一个概念 属性观测器(Property Observers): 属性观察器监控和响应属性值的变化,每次属性被设置值的时候都会调用属性观察器,甚至新的值和现在的值相同的时候也不例外. 可以为属性添加如下的一个或全部观察器: willSet在新的值被设置之前调用 didSet在新的值被设置之后立即调用 接下来开始我们的教程,先展示一下最终效果: 首先声明一个发送按钮: 复制代码 代码如下: var sendButton: UIButton! 在viewDidLoad方法中给发

  • 详解Swift的switch...case语句中break关键字的用法

    与Objective-C中这部分内容相比,在Swift中switch得到了极大的改善.这是一件非常有趣的事,因为这还是没有添加到Objective-C中,还是没有打破Objective-C是C的超集的事实. 第一件令人兴奋的地方是可以对字符串转换.这也许正是你之前想要做,却不能做的事.在Objective-C中如果要对字符串用"switch",你必须要使用多个if语句,同时要用isEqualToString:,像下面这样: if ([person.name isEqualToStrin

  • Swift使用WKWebView在iOS应用中调用Web的方法详解

    自从iOS8开始,Apple引入了WKWebView欲代替UIWebView.相比而言,WKWebView消耗内从更少,功能也更加强大.让我们来看看WKWebView怎么使用吧! 0.初始化 (1)首先需要引入WebKit库 复制代码 代码如下: #import <WebKit/WebKit.h> (2)初始化方法分为以下两种 复制代码 代码如下: // 默认初始化 - (instancetype)initWithFrame:(CGRect)frame; // 根据对webview的相关配置,

  • 使用 Swift 语言编写 Android 应用入门

    Swift标准库可以编译安卓armv7的内核,这使得可以在安卓移动设备上执行Swift语句代码.本文解释了如何在你的安卓手机上运行一个简单的"hello,world"程序. 常见问题解答 让我们来回答如下经常被问及的问题吧: 这是否以为着我能够用Swift快速的开发安卓应用? 做梦,虽然Swift编译器可以胜任在安卓设备上编译Swift代码并运行.这需要的不仅仅是用Swift标准库编写一个APP,更多的是你需要一些框架来搭建你的应用用户界面,以上这些Swift标准库不能提供. 另一方面

  • Swift编程中的switch...case语句实例解析

    Swift中的switch...case语句可以判断对象类型, Objective-C中则必须是整数. 不可以穿透,可以不写break, var rank = "A" switch rank{ case "A": //相当于if print("优") case "B": // 相当于else if print("优") case "C": // 相当于else if print(&quo

  • Swift操作Quartz 2D进行简单的绘图与坐标变换的教程

    Quartz 2D简介 Quartz 2D是苹果公司开发的一个二维图形绘制引擎,同时支持iOS和Mac系统. 它是一套基于C的API框架,提供了低级别.轻量级.高保真度的2D渲染.它能完成的工作有: 绘制图形 : 线条\三角形\矩形\圆\弧等 绘制文字 绘制\生成图片(图像) 读取\生成PDF 截图\裁剪图片 自定义UI控件 - Quartz 2D进行绘图 iOS绘图技术主要有UIKit,Quartz 2D,Core Animation和OpenGL ES.我们平常对UIKit应该不陌生,而Qu

  • spring和quartz整合,并简单调用(实例讲解)

    工作中会定时任务~简单学习一下. 第0步: 工欲善其事必先利其器,首先要做的自然是导包了. 在spring配置包扫描以及在 pom导入包 spring.xml: pom.xml 1.在spring-quartz.xml(和spring.xml同一个位置)配置相关属性 xml的头部每个人都可能不一样,这个自己要用的时候注意. quartz表达式根据自己需求去写,不列举了,这里的是1秒一次的. 2.Task包下配置类 我们这边将定时任务存放到一个包中,命名为task.用spring的自动注解serv

  • Swift与Objective C的简单对比

    现在Swift和Objective C的竞争正在飞快加剧. 这是很容易理解的,因为他们都有各自的好处,一些开发人员对对如何选择一个适合项目的编程语言产生了困惑. 首先,这两者之间的选择是没有严格的答案.在做出选择之前,要考虑很多事情,包括各种因素和特征.各自缺点和优点. 因此,这里做一个概述,以客观展示双方之间的差异和利弊,因为我们认为明智的做法是选择根据是否适合自己的开发团队和具体项目进行选择. 管理考虑 第一个考虑是根据特定团队选择.即使Swift通常被称为更简单,更平滑的语法语言,它消除了

  • Python win32com 操作Exce的l简单方法(必看)

    实例如下: from win32com.client import Dispatch import win32com.client class easyExcel: """A utility to make it easier to get at Excel. Remembering to save the data is your problem, as is error handling. Operates on one workbook at a time."

  • Python OpenCV简单的绘图函数使用教程

    目录 1.画直线的函数是cv2.line 2.画矩形的函数是cv2.rectangle 3.画圆函数是cv2.circle 4.画椭圆的函数是cv2.elipes 5.画多边形的函数是cv2.polylines 6.添加文字的函数是cv2.putText 1.画直线的函数是cv2.line cv2.line函数语法: cv2.line(img,start_point,end_point,color,thickness=0) cv2.line函数参数解释: img:需要画的图像 start_poi

  • JAVA操作HDFS案例的简单实现

    本文介绍了JAVA操作HDFS案例的简单实现,分享给大家,也给自己做个笔记 Jar包引入,pom.xml: <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-common</artifactId> <version>2.8.0</version> </dependency> <dependency> <gr

  • python 简单的绘图工具turtle使用详解

    目录 1. 画布(canvas)   1.1 设置画布大小 2. 画笔   2.1 画笔的状态   2.2 画笔的属性   2.3 绘图命令 3. 命令详解 4. 绘图举例   4.1 太阳花   4.2 绘制小蟒蛇   4.3 绘制五角星 python2.6版本中后引入的一个简单的绘图工具,叫做海龟绘图(Turtle Graphics),turtle库是python的内部库,使用导入即可 import turtle type(turtle) >>> type(turtle) <c

  • PHP使用mysqli操作MySQL数据库的简单方法

    PHP的 mysqli 扩展提供了其先行版本的所有功能,此外,由于 MySQL 已经是一个具有完整特性的数据库服务器 , 这为PHP 又添加了一些新特性 . 而 mysqli 恰恰也支持了这些新特性. 一. 建立和断开连接 与 MySQL数据库交互时,首先要建立连接,最后要断开连接,这包括与服务器连接并选择一个数据库 , 以及最后关闭连接 .与 mysqli 几乎所有的特性一样 , 这一点可以使用面向对象的方法来完成,也可以采用过程化的方式完成. 1. 创建一个 mysqli 的对象 $_mys

  • Python操作Oracle数据库的简单方法和封装类实例

    本文实例讲述了Python操作Oracle数据库的简单方法和封装类.分享给大家供大家参考,具体如下: 最近工作有接触到Oracle,发现很多地方用Python脚本去做的话,应该会方便很多,所以就想先学习下Python操作Oracle的基本方法. 考虑到Oracle的使用还有一个OracleClient的NetConfig的存在,我觉得连接起来就应该不是个简单的事情. 果然,网上找了几个连接方法,然后依葫芦却画了半天,却也不得一个瓢. 方法1:用户名,密码和监听分别作为参数 conn=cx_Ora

  • Pycharm 操作Django Model的简单运用方法

    Django中的Models 是什么? 通常一个Model对应数据库的一张数据表, Django中Models以类似的形式表现, 它包含了一些基本字段以及数据的一些行为 在Django工程 app 模块中有models.py, 输入 from django.db import models # Create your models here. class Person(models.Model): name = models.CharField(max_length=30) age = mode

随机推荐