一 、前言
iOS开发中我们经常会使用UIButton,UILabel等,这些简单的api可以让我们很快完成常规界面的开发。如果碰到一些需要自定义的界面,我们肯定需要自己绘制。今天就学习记录下iOS中关于绘制的框架CoreGraphics。
二、介绍
Core Graphics是基于Quartz 2D的一个高级绘图引擎,常用于iOS,tvOS,macOS的图形绘制应用开发。Core Graphics是对底层C语言的一个简单封装,其中提供大量的低层次,轻量级的2D渲染API。
系统的绘图框架
- UIKit
我们平常最常用的就是UIKit,其底层是依赖CoreGraphics实现的,而且绝大多数的图形界面也都是由UIKit完成,像UILabel、UIButton、UIBezierPath、UIColor简单的使用他们提供的API就能绘制到界面上,底层也是基于CoreGraphics实现。 - Core Animation
提供了强大的2D和3D动画服务,它也与UIView高度集成。iOS中的动画都是基于它实现。 - CoreGraphics
这就是本文介绍的重点,iOS中使用最多的绘图框架,常用于绘制自定义视图,纯C的API,使用Quartz2D做引擎。Core Graphics数据结构和函数可以通过CG前缀来识别。 - OpenGL-ES
这也是一套绘图框架,它是一套编程规范,具体实现由各平台自己完成。所以它是跨平台的,常用于游戏绘制。
CoreGraphics的坐标系
UIKit的坐标与Core Graphics的坐标是不一样的,UIKit的坐标默认原点在左上角,而Core Graphics的原点在左下角。通过两个坐标系之间是需要转化后才能使用的。
那为什么我们在drawRect方法中使用CoreGraphics方法绘制内容的时候可以使用UIKit的坐标系?
因为iOS系统在drawRect返回CGContext的时候,默认帮我们进行了一次变换,以方便开发者直接用UIKit坐标系进行渲染。
三、使用
-
使用须知
在介绍具体使用之前,我们需要知道,iOS的绘图必须在上下文中绘制,所以绘制前必须先获取上下文。如果是绘制图片,则先获取一个图片上下文,如果是其他视图,就需要获取一个非图片上下文。上下文可以理解为画布,在上面进行绘图。
图形上下文(注意不是图片)context,在drawRect方法中通过UIGraphicsGetCurrentContext获取。
图片上下文imageContext (不必在drawRect方法中),通过UIGraphicsBeginImageContextWithOptions:获取,然后绘制完成后,调用UIGraphicsGetImageFromCurrentImageContext获取绘制的图片,最后要记得关闭图片上下文UIGraphicsEndImageContext。
-
使用方法
1、图片上下文使用
图片类型的上下文,不需要在drawRect方法中,在普通的oc方法中就可以进行绘制:
使用Core Graphics绘制
// 获取图片上下文
UIGraphicsBeginImageContextWithOptions(CGSizeMake(60,60), NO, 0);
// 绘图
CGContextRef con = UIGraphicsGetCurrentContext();
CGContextAddEllipseInRect(con, CGRectMake(0,0,60,60));
CGContextSetFillColorWithColor(con, [UIColor blueColor].CGColor);
CGContextFillPath(con);
// 从图片上下文中获取绘制的图片
UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
// 关闭图片上下文
UIGraphicsEndImageContext();
使用UIKit绘制
// 获取图片上下文
UIGraphicsBeginImageContextWithOptions(CGSizeMake(60,60), NO, 0);
// 绘图
UIBezierPath* p = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0,0,60,60)];
[[UIColor blueColor] setFill];
[p fill];
// 从图片上下文中获取绘制的图片
UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
// 关闭图片上下文
UIGraphicsEndImageContext();
2、图形上下文使用
在view的drawRect方法中,实现重新绘制
使用Core Graphics绘制
- (void) drawRect: (CGRect) rect {
CGContextRef con = UIGraphicsGetCurrentContext();
CGContextAddEllipseInRect(con, CGRectMake(0,0,60,60));
CGContextSetFillColorWithColor(con, [UIColor greenColor].CGColor);
CGContextFillPath(con);
}
使用UIKit绘制
- (void) drawRect: (CGRect) rect {
UIBezierPath* p = [UIBezierPathbezierPathWithOvalInRect:CGRectMake(0,0,60,60)];
[[UIColor blueColor] setFill];
[p fill];
}
3、设置绘图的上下文(context)
- UIGraphicsPushContext(context):把context压入栈中,并把context设置为当前绘图上下文
- UIGraphicsPopContext():将栈顶的上下文弹出,恢复先前的上下文,但是绘图状态不变
- (void)drawRect:(CGRect)rect {
[[UIColor redColor] setFill];
UIGraphicsPushContext(UIGraphicsGetCurrentContext());
[[UIColor blackColor] setFill];
UIGraphicsPopContext();
UIRectFill(CGRectMake(100, 100, 100, 100)); // black color
}
-
使用总结
可以看到使用UIKit绘制时,我们使用了UIBezierPath。它是对CoreGraphics的进一步封装,所以使用起来更加简单。