iOS绘图
在iOS中常用有三套绘图API。一个是UIKit提供的高层API,一个是CoreGraphics提供的C语言层的API,最后一个是OpenGL ES提供的API。
iOS的绘图逻辑代码需要放在UIView的drawRect:方法里面实现,所以绘图只能发生在UIView上面。
绘图后如果我们想要显示图像可以调用
setNeedsDisplay和setNeedsDisplayInRect:。这两个方法是用来标示一个视图是否需要进行重绘,这里标示重绘并不会马上重新绘制,而是等到该RunLoop上面的任务执行完成后才回执行重绘。
触发重绘有以下几种情况:
1.当遮挡你的视图得其它视图被移动或者删除操作得时候;
2.将视图的hidden属性声明设置为No,使其从隐藏状态变为可见;
3.将视图滚出屏幕,然后重新回到屏幕;
4.显示调用视图的setNeedsDisplay或者setNeedsDisplayInRect:方法;
ios绘图周期分析
![](https://images0.cnblogs.com/blog2015/717519/201508/192124265355616.png)
UIKit绘图
比较简单,这里就说一些常用API。
设置画笔颜色:
画笔颜色分为描边颜色和填充颜色,都是用UIColor的API设置的。在drawRect方法中调用
[[UIColor anyColor] setFill]设置填充颜色。
[[UIColor anyColor] setStroke]设置描边颜色。
设置绘图区域:
UIRectFill(CGRect rect),填充某一区域 。
UIRectFrame(CGRect rect),矩形描边函数。
UIBezierPath,绘图路径类,包括了线段、弧线、矩形、圆形等等。
其中UIBezierPath可以定制主来很多很复杂的图形,这里就不具体的说UIBezierPath的api了,使用起来比较简单直接看文档就可以。
绘制图像
UIImage提供了自己的绘图方法。显示UIImage,除了添加到UIImageView中,还可以直接画到UIView上面,常用API如下:
-(void)drawAtPoint:(CGPoint)point;在某个点绘制 -(void)drawInRect:(CGRect)rect;绘制到某个矩形中 -(void)drawAsPatternInRect;绘制到某个矩形中并平铺
绘制文字
NSString的category同样提供了绘制文字的功能
-(void)drawAtPoint:(CGPoint)point withAttributes:(NSDictionary *)attrs,文本在制定点用属性绘制。 -(void)drawInRect:(CGRect)rect withAttributes:(NSDictionary *)attrs,文本在指定的矩形里绘制。
它们都可以用attrs,这和NSAttributedString很像。
CoreGraphics绘图
绘图上下文CGContextRef,CoreGraphics很类似java、C#等,需要有一个绘图上下文。
上下文中保存了要绘制内容的信息,要获得上下文需要调用。
CGContextRef UIGraphicsGetCurrentContext(void)。
常用API
移动点 void CGContextMoveToPoint(CGContextRef c, CGFloat x, CGFloat y) 画线 void CGContextAddLineToPoint(CGContextRef c, CGFloat x, CGFloat y) 闭合路径 void CGContextClosePath(CGContextRef c) 绘制路径 void CGContextDrawPath(CGContextRef c, CGPathDrawingMode mode) 设置描边颜色 void CGContextSetStrokeColorWithColor(CGContextRef c, CGColorRef color) 设置填充颜色 void CGContextSetFillColorWithColor(CGContextRef c, CGColorRef color) 绘制贝塞尔曲线,这里的参数分别是两个控制点和交点的左边,大家可以自行百度贝塞尔曲线定义 void CGContextAddCurveToPoint(CGContextRef c, CGFloat cp1x,CGFloat cp1y, CGFloat cp2x, CGFloat cp2y, CGFloat x, CGFloat y) 保存上下文 void CGContextSaveGState(CGContextRef c) 读取上下文 void CGContextRestoreGState(CGContextRef c)
常用API有很多这里只列举上面这些,剩下的可以查下API
CoreGraphics坐标系
CoreGraphics坐标系和我们平时用UIKit的坐标系是不样的,CoreGraphics的左下角为(0,0)点,而UIKit的左上角为(0,0)点。
所以我们在开发的时候,一般会先同步坐标系(CoreText也需要这么操作),应该这样写
CGContextTranslateCTM(context, 0, img.size.height);平移变化 CGContextScaleCTM(context,1,-1);缩放变换
先利用平移变换上移一个视图大小,然后在用缩放变化把高度设-1进行以x为轴的对称变换。
变换
接下来说说变换,绘图是有很多矩阵变换的,其中常用的有以下:
1.平移变换
2.缩放变换
3.旋转变换
4.x轴对称变换
5.y轴对称变换
6.坐标原点对称变换
矩阵变换CTM
CoreGraphics中提供了很多矩阵变换的API,主要有
CGContextRoatateCMT,旋转CTM,旋转变换;
CGContextScaleCTM,缩放变换;
CGContextTranslateCTM,平移变换。
仿射变换affine
仿射变换是可以重用的变换,通过多次的矩阵乘法得到变换矩阵。
CGAffineMakeRotation,创建新的旋转矩阵;
CGAffineMakeScale,创建新的缩放矩阵;
CGAffineMakeTranslation,创建新的平移矩阵;
CGAffineTransform,仿射矩阵,可以经过多次变换;
CGAffineTransformRotate,旋转矩阵;
CGAffineTransformScale,缩放矩阵;
CGAffineTransformTranslate,平移矩阵;
CGContextConcatCTM,连接到CTM变换。
我们可以创建一个CGAffineTransform,然后经过多次的仿射变换后连接到CTM进行显示。