CoreGraphics使用说明书
2016-05-22 » iOS开发基础iOS的绘图框架
iOS的绘图框架有多种,我们平常最常用的就是UIKit,其底层是依赖CoreGraphics实现的,而且绝大多数的图形界面也都是由UIKit完成,并且UIImage、NSString、UIBezierPath、UIColor等都知道如何绘制自己,也提供了一些方法来满足我们常用的绘图需求。除了UIKit,还有CoreGraphics、Core Animation,Core Image,OpenGL ES等多种框架,来满足不同的绘图要求。各个框架的大概介绍如下:
- UIKit:最常用的视图框架,封装度最高,都是OC对象
- CoreGraphics:主要绘图系统,常用于绘制自定义视图,纯C的API,使用Quartz2D做引擎
- CoreAnimation:提供强大的2D和3D动画效果
- CoreImage:给图片提供各种滤镜处理,比如高斯模糊、锐化等
- OpenGL-ES:主要用于游戏绘制,但它是一套编程规范,具体由设备制造商实现
绘图的了解
绘图周期
运行循环会遍历所有待处理的 UIView/CAlayer 以执行实际的绘制和调整,并更新 UI 界面,这是一个绘图周期。
绘制操作只发生在主线程
视图绘制
UIView的 drawRect: 方法 进行绘制,如果调用一个视图的 setNeedsDisplay,该视图就会被标记为重新绘制,在下一次绘图周期中会调用drawRect: 重新绘制。
视图布局
调用UIView的layoutSubviews方法。如果调用一个视图的setNeedsLayout方法,那么该视图就被标记为需要重新布局,UIKit会自动调用layoutSubviews方法及其子视图的layoutSubviews方法。
在绘图时,我们应该尽量多使用布局,少使用绘制,是因为布局使用的是GPU,而绘制使用的是CPU。GPU对于图形处理有优势,而CPU要处理的事情较多,且不擅长处理图形,所以尽量使用GPU来处理图形。
CoreGraphics
###
1.context 绘图上下文
iOS的绘图必须在一个上下文中绘制,所以在绘图之前要获取一个上下文。如果是绘制图片,就需要获取一个图片的上下文;如果是绘制其它视图,就需要一个非图片上下文。对于上下文的理解,可以认为就是一张画布,然后在上面进行绘图操作。
获取上下文方法
1、重载UIView的 drawrect: 方法
在我们执行任何绘制代码前,该方法自动配置好绘图上下文,我们只需要通过 UIGraphicsGetCurrentContext 方法就可以获取到当前绘图上下文用于绘制操作。
2、自己生成绘图上下文
当不是在 drawrect:方法中执行绘制操作,imageContext 图片上下文,可以通过UIGraphicsBeginImageContextWithOptions:获取一个图片上下文,然后绘制完成后,调用UIGraphicsGetImageFromCurrentImageContext获取绘制的图片,最后要记得关闭图片上下文UIGraphicsEndImageContext。
2.绘图状态
1、pop 、 push (设置绘图的上下文环境(context))
push:UIGraphicsPushContext(context)把context压入栈中,并把context设置为当前绘图上下文
pop:UIGraphicsPopContext将栈顶的上下文弹出,恢复先前的上下文,但是绘图状态不变
override func draw(_ rect: CGRect) {
UIColor.red.setFill()
let context = UIGraphicsGetCurrentContext()
UIGraphicsPushContext(context!)
UIColor.blue.setFill()
UIGraphicsPopContext()
UIRectFill(self.bounds)
}//结果显示的是蓝色
2、save 、restore (设置绘图的状态)
save:CGContextSaveGState 压栈当前的绘图状态,仅仅是绘图状态,不是绘图上下文
restore:恢复刚才保存的绘图状态
override func draw(_ rect: CGRect) {
UIColor.red.setFill()
let context = UIGraphicsGetCurrentContext()
context?.saveGState()
context?.setFillColor(UIColor.blue.cgColor)
context?.restoreGState()
context?.fill(self.bounds)
}//结果显示的是红色
3、CGPathRef / UIBezierPath
图形的绘制需要绘制一个路径,然后再把路径渲染出来,而CGPathRef就是CoreGraphics框架中的路径绘制类,UIBezierPath是封装CGPathRef的面向OC的类,使用更加方便,但是一些高级特性还是不及CGPathRef。
4.绘图方法
1、图片类型的上下文绘图
不在复写方法中进行
UIGraphicsBeginImageContextWithOptions(CGSize(width: 100, height: 100), false, 0)
let context = UIGraphicsGetCurrentContext()
context?.addEllipse(in: CGRect(x: 0, y: 0, width: 100, height: 100))
context?.setFillColor(UIColor.red.cgColor)
context?.fillPath()
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
let imageView = UIImageView(image: image)
imageView.frame = CGRect(x: 0, y: 100, width: 100, height: 100)
view.addSubview(imageView)
2、draw(_ rect: CGRect)
在view子类的 draw(_ rect: CGRect) 方法进行重绘
3、draw(_ layer: CALayer, in ctx: CGContext)
在view子类的 draw(_ layer: CALayer, in ctx: CGContext) 方法进行重绘
4、 draw(in ctx: CGContext)
在CALayer中绘制
5、具体的几个绘制
Shadows阴影使用
ctx.setShadow(offset: CGSize(width: 2, height: 2), blur: 0.5, color: UIColor.red.cgColor)
offset: 偏移量
blur: 透明度
color: 颜色
Gradients渐变效果使用
绘制
绘制一个由上到下的 红-橙 渐变
let array = [UIColor.red.cgColor, UIColor.orange.cgColor] as CFArray
ctx.drawLinearGradient(CGGradient(colorsSpace: CGColorSpaceCreateDeviceRGB(), colors: array, locations: [0.0, 1.0])!, start: CGPoint(x: 0, y: 0), end: CGPoint(x: 100, y: 100), options: [])
CAGradientLayer
绘制一个横向5色彩虹
let myLayer = CAGradientLayer()
myLayer.position = CGPoint(x: 100, y: 100)
myLayer.bounds = CGRect(x: 0, y: 0, width: 200, height: 100)
myLayer.colors = [UIColor.red.cgColor, UIColor.orange.cgColor,UIColor.yellow.cgColor, UIColor.green.cgColor,UIColor.blue.cgColor]
myLayer.locations = [NSNumber(floatLiteral: 0.2),NSNumber(floatLiteral: 0.4),NSNumber(floatLiteral: 0.6),NSNumber(floatLiteral: 0.8),NSNumber(floatLiteral: 1.0)]
myLayer.startPoint = CGPoint(x: 0, y: 0)
myLayer.endPoint = CGPoint(x: 1.0, y: 0)
Transparency Layers使用
透明图层
https://blog.csdn.net/rhljiayou/article/details/10144993