看了几篇网上图形上下文栈的讲解,不知道是我理解有问题,还是没找到好文章,还是压根作者也不是特别明白,欺骗我。最后决定自己写一个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.出战的上下文,将样式赋值给当前样式,然后释放