图形上下文栈

看了几篇网上图形上下文栈的讲解,不知道是我理解有问题,还是没找到好文章,还是压根作者也不是特别明白,欺骗我。最后决定自己写一个demo,好好理解一下


什么是图像上下文栈?
我的理解就是,保存当前的上下文样式,当需要的时候直接还原,不用一直写垃圾代码

将来要做的样式和代码解释图
- (void)drawRect:(CGRect)rect {
    //图形上下文栈
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    //第一根线,头部是圆角,线是红色的,线宽10px
    CGContextMoveToPoint(ctx, 10, 10);
    CGContextAddLineToPoint(ctx, 10, 90);
    CGContextSetLineCap(ctx, kCGLineCapRound);
    CGContextSetLineWidth(ctx, 4);
    [[UIColor redColor] set];
    //保存第一个图形上下文样式
    CGContextSaveGState(ctx);
    CGContextStrokePath(ctx);
    
    //第2根线,头部是直角,线是绿色的,线宽10px
    CGContextMoveToPoint(ctx, 30, 10);
    CGContextAddLineToPoint(ctx, 30, 43);
    CGContextSetLineWidth(ctx, 12);
    CGContextSetLineCap(ctx, kCGLineCapButt);
    [[UIColor greenColor] set];
    //保存第二个图形上下文样式
    CGContextSaveGState(ctx);
    CGContextStrokePath(ctx);
    
    
    //第3根线,头部是kCGLineCapSquare,线是橙色的,线宽20px
    CGContextMoveToPoint(ctx, 60, 40);
    CGContextAddLineToPoint(ctx, 40, 180);
    CGContextSetLineWidth(ctx, 4);
    CGContextSetLineCap(ctx, kCGLineCapSquare);
    [[UIColor orangeColor] set];
    //保存第三个图形上下文样式
    CGContextSaveGState(ctx);
    CGContextStrokePath(ctx);
    
    //直接绘制一个直线,看看是什么样子的(其实是和第三个样式相同)
    CGContextMoveToPoint(ctx, 90, 10);
    CGContextAddLineToPoint(ctx, 90, 99);
    CGContextStrokePath(ctx);
    
    //从图像上下文中获取一个数据试试
    CGContextRestoreGState(ctx);
    CGContextMoveToPoint(ctx, 120, 10);
    CGContextAddLineToPoint(ctx, 120, 130);
    CGContextStrokePath(ctx);
    
    //突然想绘制第四个线,和第一根线一样
    CGContextMoveToPoint(ctx, 140, 10);
    CGContextAddLineToPoint(ctx, 140, 99);
    CGContextStrokePath(ctx);
    
    //突然想绘制一个圆形,和第一根线的属性基本一致
    //即使使用一个图形上下文,也不影响使用属性和绘制多个图形
    CGContextAddArc(ctx, 200, 60, 20, 0, 189/360.0*2*M_PI, NO);
    CGContextStrokePath(ctx);
    
    //从图形上下文栈中在获取一个试试
    CGContextRestoreGState(ctx);
    CGContextMoveToPoint(ctx, 250, 10);
    CGContextAddLineToPoint(ctx, 250, 100);
    CGContextStrokePath(ctx);
    
![Uploading Simulator Screen Shot 2016年8月7日 下午12.55.32_489724.png . . .]
    //再去从图形上下文栈中在获取一个
    CGContextRestoreGState(ctx);
    CGContextMoveToPoint(ctx, 300, 10);
    CGContextAddLineToPoint(ctx, 300, 100);
    CGContextStrokePath(ctx);
    
}

注意:
1.入栈CGContextSaveGState(cox)
2.出栈CGContextRestoreGState(ctx);
3.如果出战的次数大于入栈,就会奔溃
4.什么是入栈?就是拷贝当前图形上下文,然后放到栈中,因为使用CGContextRef只有一个图形上下文,所以要拷贝!
5.如何理解拷贝图形上下文,我们操作的图形上下文成为A,此时如果图形上下文就设置了[[UIColor redColor] set]这一个属性,拷贝A,入栈(我们把拷贝后入栈的成为B),将来不论以后我们如何操作A,设置了多少属性,以后的都是A这个模样,但是我们出战B,将来使用的样式都是只有一个[[UIColor redColor] set]的状态!说白了,就是保存某种图形上下文的状态!
5.出战的上下文,将样式赋值给当前样式,然后释放

推荐阅读更多精彩内容