Quartz2D-定时器AND图形上下文状态栈

Posted by Chen on September 23, 2016

# #07-定时器,雪花

####1.定时器雪花整体思路: 先在控制器View面绘制一个雪花. 在View加载完毕后,添加一个定时器. 在定时器方法当中调用得绘方法. 在绘图方法当不段的去修改雪花的Y值. 当雪花的Y值超过屏幕的高度时,让雪花的Y值重新设为0.从最顶部开始. ####2.添加定时器实现方案 第一种采用NSTime 第二种采用CADisplayLink 最终采用CADisplayLink方案. #####2.1为什么采用CADisplayLink方案不用NSTime? 首先要了解setNeedsDisplay setNeedsDisplay底层会调用DrawRect方法重绘. 但是它不是立马就进行重绘.它仅仅是设置了一个重绘标志,等到下一次屏幕刷新的时候才会调用DrawRect方法. 如果使用NSTime的话,假设是0.01调用一次重绘.假设屏幕0.02秒的时候它才刷新一次.中间就会等0.01秒. 也就是每次都会等0.01秒这样累加上去.让变的越来越卡顿. 使用CADisplayLink时,它的定时器方法就是屏幕每次刷新的时候就会调用(通常屏幕一秒钟刷新60次) 它和setNeedsDisplay调用DrawRect方法的时机正好吻合,不会出间等待间隔.不会出现屏幕卡顿现象.

CADisplayLink 与 NSTimer 有什么不同

iOS设备的屏幕刷新频率是固定的,CADisplayLink在正常情况下会在每次刷新结束都被调用,精确度相当高。 NSTimer的精确度就显得低了点,比如NSTimer的触发时间到的时候,runloop如果在阻塞状态,触发时间就会推迟到下一个runloop周期。并且 NSTimer新增了tolerance属性,让用户可以设置可以容忍的触发的时间的延迟范围。 *CADisplayLink使用场合相对专一*,适合做UI的不停重绘,比如自定义动画引擎或者视频播放的渲染*NSTimer的使用范围要广泛的多*,各种需要单次或者循环定时处理的任务都可以使用。在UI相关的动画或者显示内容使用 CADisplayLink比起用NSTimer的好处就是我们不需要在格外关心屏幕的刷新频率了,因为它本身就是跟屏幕刷新同步的。 哈哈哈

原文链接:CADisplayLink #####2.2如何使用CADisplayLink添加定时器? Target:哪个对象要监听方法. selector:监听的方法名称. CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(setNeedsDisplay)]; 想要让CADisplayLink工作,必须得要把它添加到主运行循环. 只要添加到主运行循环, 跟模式没有关系 [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; ####3.具体实现代码如下: -(void)awakeFromNib{ CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(setNeedsDisplay)]; [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; }

  • (void)drawRect:(CGRect)rect { if(_snowY > rect.size.height){ _snowY = 0; } UIImage *image = [UIImage imageNamed:@”雪花”]; [image drawAtPoint:CGPointMake(0, _snowY)]; _snowY += 10; }

# #08-图形上下文状态栈 简单介绍由来

深入图形上下文

上下文状态栈为内存中的一块区域,它用来保存当前上下文的状态.

我们获取的图层上下文当中其实两块区域,

  • 一个是存放添加的路径,
  • 一个是用来保存用户设置的状态,

    这些状态包括线条的颜色,线宽等. 当我们把上下文的内容渲染到View上面的时候, 它会自动将设置的所有上下文状态运行到保存的路径上面显示到View上面. 如果想要有多种状态,可以先把路径渲染到View上面, 再从新添加路径.添加完路径之后,重新设置上下文的状态. 再把新设置的上下文状态渲染到View上面. 我们可以利用上下文状态栈的方式,在设置状态之前,把之前的状态保存到上下文状态栈里面. 下一次想要再使用之前的状态时, 可以从上下文状态当中取出之前保存的上下文状态. 1.如何把上下文状态保存到上下文状态栈? CGContextSaveGState(ctx); 2.如何从上下文状态栈中取出上下文状态? CGContextRestoreGState(ctx); ###图形上下文矩阵操作 上下文的矩阵操作其实就是修改上下文的形变, 主要有以下几种 平移 CGContextTranslateCTM(ctx, 100, 100); 旋转 CGContextRotateCTM(ctx, M_2_PI); 缩放 CGContextScaleCTM(ctx, 0.5, 0.5); 注意:上下文操作必须得要在添加路径之前去设置