Core Graphics
Core Graphics入门
想必每个第一次接触Core Graphics的开发者都被无数的API、混乱的代码逻辑折腾得头疼不已,甚至望而却步。即使是绘制一个简单的矩形也看上去非常繁琐。本文换一个角度,整理一下有关Core Graphics的知识,也算作是这段时间学习的总结。
Core Graphics和UIKit的区别
首先从概念上了解一下:
根据苹果的描述,UIKit是我们最容易也是最常接触到的框架。绝大多数图形界面都由UIKit完成。但是UIKit依赖于Core Graphics框架,也是基于Core Graphics框架实现的。如果想要完成某些更底层的功能或者追求极致的性能,那么依然推荐使用Core Graphics完成。
Core Graphics和UIKit在实际使用中也存在以下这些差异:
- Core Graphics其实是一套基于C的API框架,使用了Quartz作为绘图引擎。这也就意味着Core Graphics不是面向对象的。
- Core Graphics需要一个图形上下文(Context)。所谓的图形上下文(Context),说白了就是一张画布。这一点非常容易理解,Core Graphics提供了一系列绘图API,自然需要指定在哪里画图。因此很多API都需要一个上下文(Context)参数。
- Core Graphics的图形上下文(Context)是堆栈式的。只能在栈顶的上下文(画布)上画图。
- Core Graphics中有一些API,名称不同却有着相似的功能,新手只需要掌握一种,并能够看懂其他的即可。
从一行代码说起
下面这行代码应该是很多人最早也是最常写的代码。它简单到我们根本不用思考它的本质。
[self.view addSubview:myButton];
细想一下,UIButton也是继承自UIView。这段代码表示,UIKit绘图的基本思想是通过UIView的叠加实现最终的整体效果。它主要涉及三个内容:画布、被添加的控件和添加方法。这里的self.view其实就充当了一张画布。通过添加不同的UI控件达到最终效果。我们顺着这个线索整理一下Core Graphics的编程思路。
Core Graphics的基本使用
为了使用Core Graphics来绘图,最简单的方法就是自定义一个类继承自UIView,并重写子类的drawRect方法。在这个方法中绘制图形。
Core Graphics必须一个画布,才能把东西画在这个画布上。在drawRect方法方法中,我们可以直接获取当前栈顶的上下文(Context)。下面的代码演示了具体操作步骤:
- (void)drawRect:(CGRect)rect {CGContextRef ctx = UIGraphicsGetCurrentContext();
}
现在我们已经完成了Core Graphics绘图的三分之一——创建一个画布。
接下来需要考虑被画上去的东西。这在UIKit中往往是一个UI控件,如Button、Label等。而在Core Graphics中通常表现为一些基本图形:三角形、矩形、圆形、以及这些图形的边框等。
这通常会涉及到非常多的API,但是如果总结一下不难发现,任何一个要绘制的东西(为了避免混淆就不称为对象了)一定有一个边框,或者称为边界。在一个几英寸的屏幕上画出无界的图形是不可能的。所以一旦确定了一个边框,我们就可以设置边框的各种绘图属性、边框内部区域的绘图属性、绘制边框还是内部区域等。
这就引出了Core Graphics中的路径(Path)的概念。在前一段代码的基础上演示路径的使用:
- (void)drawSomething{CGContextRef context = UIGraphicsGetCurrentContext();//获取上下文CGMutablePathRef path = CGPathCreateMutable();//创建路径CGPathMoveToPoint(path, nil, 20, 50);//移动到指定位置(设置路径起点)CGPathAddLineToPoint(path, nil, 20, 100);//绘制直线(从起始位置开始)CGContextAddPath(context, path);//把路径添加到上下文(画布)中
}
这里通过CGPathCreateMutable方法创建了一个路径。路径的外在表现就像一条折线。为了绘制一条路径,需要用CGPathMoveToPoint函数指定路径的起点。CGPathAddLineToPoint函数表示在路径的最后结束点和新的点之间再加一条直线。相当于拓展了原来路径。通过这样的简单的点的累加,可以绘制非常复杂的折线。
但这存在两个问题:
- 绘制矩形等规则多边形的过程过于繁琐
- 无法绘制曲线。
这些问题Core Graphics早已提供了解决办法。注意到之前我们添加了一个非常普通的自定义路径。Core Graphics中还提供了很多预先设置好的路径。不妨在drawRect方法中输入“cgcontextadd”试试看。
这些方法由Core Graphics提供,可以用来绘制圆形、椭圆、矩形、二次曲线等路径。创建完路径后还要记得调用CGContextAddPath方法将路径添加到上下文中。路径只是我们画的一条线而已,不把他画到上,他就没有什么卵用。
添加好路径后,就要开始画图了。正如前面提出的问题所说,画图的时候需要考虑画不画边框、画不画边框内部的区域,边框的粗细、颜色、内部区域颜色等问题。Core Graphics提供了另一个方法集合”CGContextSet”来进行这些设置。常见的设置内容如下:
- (void)drawSomething{CGContextRef context = UIGraphicsGetCurrentContext();//获取上下文CGMutablePathRef path = CGPathCreateMutable();//创建路径CGPathMoveToPoint(path, nil, 20, 50);//移动到指定位置(设置路径起点)CGPathAddLineToPoint(path, nil, 20, 100);//绘制直线(从起始位置开始)CGContextAddPath(context, path);//把路径添加到上下文(画布)中//设置图形上下文状态属性CGContextSetRGBStrokeColor(context, 1.0, 0, 0, 1);//设置笔触颜色CGContextSetRGBFillColor(context, 0, 1.0, 0, 1);//设置填充色CGContextSetLineWidth(context, 2.0);//设置线条宽度CGContextSetLineCap(context, kCGLineCapRound);//设置顶点样式CGContextSetLineJoin(context, kCGLineJoinRound);//设置连接点样式CGFloat lengths[2] = { 18, 9 };CGContextSetLineDash(context, 0, lengths, 2);CGContextSetShadowWithColor(context, CGSizeMake(2, 2), 0, [UIColor blackColor].CGColor);CGContextDrawPath(context, kCGPathFillStroke);//最后一个参数是填充类型
}
设置属性的前三行就不再解释了,看一些注释足矣。顶点指的是路径的起始点和结束点,连接点指的是路径中的转折点(折现才有)。SetLineDash用于绘制虚线,具体用法参见——《IOS中使用Quartz 2D绘制虚线》。SetShadow方法用于绘制阴影,第二个参数是一个CGSize对象,用于表示阴影偏移量,第三个参数表示模糊度,数值越大,阴影越模糊,第一个参数是一个CGColor,表示阴影颜色,需要由UIColor转换得到。
至此,我们完成了Core Graphics绘图的第二步,也是最复杂的一部分:设置绘图内容。这相当于此前那行代码的中的UI控件。
设置好了绘图的属性之后,就可以调用CGContextDrawPath方法绘图了。第一个参数表示要在哪一个上下文中绘图,第二个参数表示填充类型。在填充类型中可以选择只绘制边框、只填充、同时绘制边框和填充内部区域、奇偶规则填充等。
从方法名不难看出,但是也需要注意的是,这些设置都是对上下文(context)生效的。这样会导致,所有的边框颜色、粗细都一样。一个简单的解决办法就是在需要修改设置之前调用一次CGContextDrawPath方法绘图。再修改设置,修改设置之后再次绘制。
图画完了,还得做一下清理工作。CGPathCreateMutable方法返回的路径是一个Core Fundation Object。而这并不在ARC的管理范围之内。所以需要手动释放对象。
- (void)drawRect:(CGRect)rect {CGContextRef context = UIGraphicsGetCurrentContext();//获取上下文CGMutablePathRef path = CGPathCreateMutable();//创建路径/*绘图*/CGPathRelease(path);
}
这样就完成了Core Graphics绘图的第三部分——开始绘图。
再总结一下使用Core Graphics绘图的步骤:
- 获取上下文(画布)
- 创建路径(自定义或者调用系统的API)并添加到上下文中。
- 进行绘图内容的设置(画笔颜色、粗细、填充区域颜色、阴影、连接点形状等)
- 开始绘图(CGContextDrawPath)
- 释放路径(CGPathRelease)
Core Graphics相关推荐
- 【转】使用Core Graphics绘画一个山寨微信icon
文章出处:http://www.jianshu.com/p/1008f9803759# 先看最终效果: - - - 绘画这个纯属周末雨天无聊,这里使用的都是Core Graphics上很基本的几个方法 ...
- 使用 Core Graphics 绘制基本形状
作者:Arthur Knopper,原文链接,原文日期:2015-08-31 译者:lfb_CD:校对:千叶知风:定稿:shanks Core Graphics是Cocoa和Cocoa Touch所共 ...
- Core Graphics 定制UIVIew 处理图片
许多UIView的子类,如UIButton或UILabel,它们的形状都是系统固定的.但是,对于一些特殊的情况,我们需要绘制产品狗想要的图形.那么等待我们的只有两个选择:第一,可以使用UIImageV ...
- iOS绘图UIBezierPath 和 Core Graphics框架
前言 iOS系统本身提供了两套绘图的框架,即UIBezierPath 和 Core Graphics.而前者所属UIKit,其实是对Core Graphics框架关于path的进一步封装,所以使用起来 ...
- 使用Core Graphics绘画一个山寨微信icon
使用Core Graphics绘画一个山寨微信icon 最终效果: 绘画这个纯属周末雨天无聊,这里使用的都是Core Graphics上很基本的几个方法,对新手(我也是新手)来说还是有帮助的.下面说下 ...
- iOS 图形处理 Core Graphics Quartz2D 教程
Core Graphics Framework是一套基于C的API框架,使用了Quartz作为绘图引擎.它提供了低级别.轻量级.高保真度的2D渲染.该框架可以用于基于路径的绘图.变换.颜色管理.脱屏渲 ...
- iOS图形编辑之Core Graphics
Core Graphics Framework是一套基于C的API框架,使用了Quartz作为绘图引擎.它提供了低级别.轻量级.高保真度的2D渲染.该框架可以用于基于路径的绘图.变换.颜色管理.脱屏渲 ...
- iOS开发--Core Graphics绘图
一. Core Graphics简介 Core Graphics是一个基于C的绘图专用的API族,它经常被称为QuartZ或QuartZ 2D,是一个二维绘图引擎,同时支持iOS和Mac系统.它提供了 ...
- Swift Core Graphics教程之Gradients 与 Context
原文链接 : Core Graphics Tutorial Part 2: Gradients and Contexts 原文作者 : caroline 译文出自 : 开发技术前线 译者 : Harr ...
最新文章
- 计算当前时间对应的本周一、上周一
- 阿里云网站80端口无法访问
- stdthread(6)并发mutex
- 埋点、数仓到中台:数据体系的从0到1
- 科大星云诗社动态20210207
- Linux C: 文件操作相关的系统调用
- hdu2648 Shopping-map容器
- cas单点登录系统:客户端(client)详细配置(包含统一单点注销配置)
- CVPR2021 P2GAN:提高图像风格迁移的鲁棒性
- C# WebService 基础实例
- 华为还是输了!双11战报出炉,离苹果仍有距离
- string services
- SOA的关键是什么?
- 开4核后用哪个软件测试稳定性,测试CPU的稳定性的方法
- 关于PCBLayout的一些具体细节的认识(能力有限,请大家多多指点)
- excel组合汇总_Excel汇总20150112
- YTU OJ 2476 Problem B C++习题 继承与组合
- mysql - rank函数的使用
- 巧用python求解逻辑题,特简单!
- 内存泄露(memery leak)避免方法
热门文章
- JoVE微生物组专刊征稿,写方法拍视频教程发SCI(宏基因组公众号专属福利)
- Nature:首个肠道微生物对药物代谢影响的系统性研究
- pandas使用groupby函数计算dataframe数据中每个分组的N个数值的滚动标准差(rolling std)、例如,计算某公司的多个店铺每N天(5天)的滚动销售额标准差
- R语言union函数计算数据对象(vector、list、dataframe)的并集:union函数计算两个vector向量、dataframe、列表list的并集
- R语言进行主成分分析(PCA)、使用prcomp函数进行主成分分析:碎石图可视化(scree plot)、R通过条形图(bar plot)来可视化主成分分析的碎石图(scree plot)
- Pandas批量删除dataframe列名中的前缀实战:使用lstrip函数批量删除列名中的前缀(prefix)、使用replace函数批量删除列名中的前缀(prefix)
- R语言可视化面积图(area chart)移除轴标签与实际图形之间的空白区域实战:默认的面积图、移除轴标签与实际图形之间的空白区域
- R语言使用ggplot2包geom_jitter()函数绘制分组(strip plot,一维散点图)带状图(改变图例位置、移除图例)实战
- Python使用matplotlib绘图并去除颜色样条colorbar实战:remove colorbar from figure in matplotlib
- Bicolor的使用