iOS绘图

iOS绘图java

在iOS中经常使用有三套绘图API。一个是UIKit提供的高层API,一个是CoreGraphics提供的C语言层的API,最后一个是OpenGL ES提供的API。ios

iOS的绘图逻辑代码须要放在UIView的drawRect:方法里面实现,因此绘图只能发生在UIView上面。api

绘图后若是咱们想要显示图像能够调用安全

setNeedsDisplay和setNeedsDisplayInRect:。这两个方法是用来标示一个视图是否须要进行重绘,这里标示重绘并不会立刻从新绘制,而是等到该RunLoop上面的任务执行完成后才回执行重绘。函数

触发重绘有如下几种状况:oop

1.当遮挡你的视图得其它视图被移动或者删除操做得时候;spa

2.将视图的hidden属性声明设置为No,使其从隐藏状态变为可见;线程

3.将视图滚出屏幕,而后从新回到屏幕;code

4.显示调用视图的setNeedsDisplay或者setNeedsDisplayInRect:方法;orm

 

ios绘图周期分析

经过下面这个例子来分析
progressView.hidden = NO;
[self doSomethingTimeConsuming];
progressView.hidden = YES;
第一行代码progress.hidden = NO;根本没有效果,这行代码不会使进度视图在执行耗时操做时显示出来。不管这个方法运行多久,都不会看到视图显示出来。
 
全部的绘制都发生在主线程,只要代码运行在主线程,就没有东西能够绘制。这就是不要在主线程中执行长时间运行操做的一个缘由。这不只会阻碍绘制更新,还会阻碍事件处理(好比响应触摸事件)。只要代码在主线程上,应用对于用户其实就是“功能挂起的”。若是主线程例程返回足够快,这些变化根本就察觉不到。
你可能会想:“那我就在后台线程运行个人绘图指令。”一般是没法作到这一点的,由于对于当前的UIKit上下文来讲绘图不是线程安全的。任何在后台线程修改视图的尝试都会致使未定义的行为,包括绘制出错或崩溃。
这个行为并非须要解决的问题。绘图时间实质是ios在有限的硬件上渲染复杂绘图的功能。

 

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进行显示。

相关文章
相关标签/搜索