[iOS]上下文的理解
来源:互联网 发布:电信网络诈骗定什么罪 编辑:程序博客网 时间:2024/05/17 02:49
1.关于图形上下文栈的操作
void CGContextSaveGState(CGContextRef c)
void CGContextRestoreGState(CGContextRef c)
2.用实例说明图形上下文栈的好处
2.1先创建一个project,然后自定义一个view,并且让这个自定义的view成为控制器的view
2.2.用代码创建两根线运行结果如下
- #import "MJView.h"
- @implementation MJView
- - (id)initWithFrame:(CGRect)frame
- {
- self = [super initWithFrame:frame];
- if (self) {
- // Initialization code
- }
- return self;
- }
- - (void)drawRect:(CGRect)rect
- {
- // 1.获得上下文
- CGContextRef ctx = UIGraphicsGetCurrentContext();
- // 设置绘图状态
- CGContextSetLineWidth(ctx, 10);
- [[UIColor redColor] set];
- CGContextSetLineCap(ctx, kCGLineCapRound); //设置画线的首位为圆状
- // 第1根线
- CGContextMoveToPoint(ctx, 50, 50);
- CGContextAddLineToPoint(ctx, 120, 190);
- //渲染
- CGContextStrokePath(ctx);
- <pre code_snippet_id="643034" snippet_file_name="blog_20150413_1_8397810" name="code" class="objc"> // 设置绘图状态
- CGContextSetLineWidth(ctx, 10);
- [[UIColor redColor] set];
- CGContextSetLineCap(ctx, kCGLineCapRound); //设置画线的首位为圆状
2.3需求,要让右边的那根线不要拥有右边那根线的样式,一切还原(也就是让第二根线不受第一根线设置的状态的影响)
void CGContextSaveGState(CGContextRef c)
void CGContextRestoreGState(CGContextRef c)
// 1.获得上下文
CGContextRef ctx =UIGraphicsGetCurrentContext();
// 2.将栈顶的上下文出栈,替换当前的上下文
CGContextRestoreGState(ctx);
2.3.1运行结果如下
- //
- // MJView.m
- #import "MJView.h"
- @implementation MJView
- - (id)initWithFrame:(CGRect)frame
- {
- self = [super initWithFrame:frame];
- if (self) {
- // Initialization code
- }
- return self;
- }
- - (void)drawRect:(CGRect)rect
- {
- // 1.获得上下文
- CGContextRef ctx = UIGraphicsGetCurrentContext();
- // 将ctx拷贝一份放到栈中
- CGContextSaveGState(ctx);
- // 设置绘图状态
- CGContextSetLineWidth(ctx, 10);
- [[UIColor redColor] set];
- CGContextSetLineCap(ctx, kCGLineCapRound); //设置画线的首位为圆状
- // 第1根线
- CGContextMoveToPoint(ctx, 50, 50);
- CGContextAddLineToPoint(ctx, 120, 190);
- //渲染
- CGContextStrokePath(ctx);
- // 将栈顶的上下文出栈,替换当前的上下文
- CGContextRestoreGState(ctx);
- // 第2根线
- CGContextMoveToPoint(ctx, 10, 70);
- CGContextAddLineToPoint(ctx, 220, 290);
- //渲染
- CGContextStrokePath(ctx);
- // CGContextDrawPath(ctx, kCGPathStroke); 渲染也可以用这种方式(前面参数为上下文,后面参数为枚举可确定渲染方式
- }
- @end
3.详细分析绘图本质(图形上下文栈)
对如下代码作分析
- (void)drawRect:(CGRect)rect
{
// 1.获得上下文
CGContextRef ctx =UIGraphicsGetCurrentContext();
// 设置绘图状态
CGContextSetLineWidth(ctx,10);
[[UIColorredColor] set];
CGContextSetLineCap(ctx,kCGLineCapRound);//设置画线的首位为圆状
//第1根线(这个路径暂时添加到上下文对象中)
CGContextMoveToPoint(ctx,50,50);
CGContextAddLineToPoint(ctx,120,190);
//渲染(把当前上下文保存的所有路径都一次性渲染到view上面)
CGContextStrokePath(ctx);
// 第2根线
CGContextMoveToPoint(ctx,10,70);
CGContextAddLineToPoint(ctx,220,290);
//渲染
CGContextStrokePath(ctx);
// CGContextDrawPath(ctx, kCGPathStroke);
}
内存首先有一个view(画板)如右图
然后有一个上下文对象如左图(保存绘图路径、绘图状态以及绘图到哪里去)
执行如下代码后内存为下面这样的状态
CGContextRef ctx =UIGraphicsGetCurrentContext();
// 将ctx拷贝一份放到栈中
CGContextSaveGState(ctx);
// 设置绘图状态
CGContextSetLineWidth(ctx,10);
[[UIColorredColor] set];
CGContextSetLineCap(ctx,kCGLineCapRound);//设置画线的首位为圆状
//第1根线(这个路径暂时添加到上下文对象中)
CGContextMoveToPoint(ctx,50,50);
CGContextAddLineToPoint(ctx,120,190);
接着执行下面一行代码后内存为下面的状态
//渲染(把当前上下文保存的所有路径都一次性渲染到view上面)
CGContextStrokePath(ctx);
当执行下面几行代码后内存为如下的状态
// 第2根线
CGContextMoveToPoint(ctx,10,70);
CGContextAddLineToPoint(ctx,220,290);
执行下面代码后内存为如下图
//渲染
CGContextStrokePath(ctx);
思路一:
完整代码为
- (void)drawRect:(CGRect)rect
{
// 1.获得上下文
CGContextRef ctx =UIGraphicsGetCurrentContext();
// 设置绘图状态
CGContextSetLineWidth(ctx,10);
[[UIColorredColor] set];
CGContextSetLineCap(ctx,kCGLineCapRound);//设置画线的首位为圆状
//第1根线(这个路径暂时添加到上下文对象中)
CGContextMoveToPoint(ctx,50,50);
CGContextAddLineToPoint(ctx,120,190);
//渲染(把当前上下文保存的所有路径都一次性渲染到view上面)
CGContextStrokePath(ctx);
// 第2根线
// 设置绘图状态
CGContextSetLineWidth(ctx,1);
[[UIColorblackColor] set];
CGContextSetLineCap(ctx,kCGLineCapbutt); CGContextMoveToPoint(ctx,10,70);
CGContextAddLineToPoint(ctx,220,290);
//渲染
CGContextStrokePath(ctx);
// CGContextDrawPath(ctx, kCGPathStroke);
}
也就是在画第二根线的时候增加如下代码把上下文状态覆盖掉
// 设置绘图状态
CGContextSetLineWidth(ctx,1);
[[UIColorblackColor] set];
CGContextSetLineCap(ctx,kCGLineCapbutt);
这个时候内存状态为:
当执行下面代码后内存为
CGContextMoveToPoint(ctx, 10,70);
CGContextAddLineToPoint(ctx,220,290);
当对第二根线渲染后
CGContextStrokePath(ctx);
思路二:
思路一可以实现但是很麻烦,假设第一根线有很多状态就必须要再写很多状态来覆盖掉才行,所有这就采用图形上下文栈
此时完成代码为:
- (void)drawRect:(CGRect)rect
{
// 1.获得上下文
CGContextRef ctx =UIGraphicsGetCurrentContext();
// 将ctx拷贝一份放到栈中
CGContextSaveGState(ctx);
// 设置绘图状态
CGContextSetLineWidth(ctx,10);
[[UIColorredColor] set];
CGContextSetLineCap(ctx,kCGLineCapRound);//设置画线的首位为圆状
//第1根线(这个路径暂时添加到上下文对象中)
CGContextMoveToPoint(ctx,50,50);
CGContextAddLineToPoint(ctx,120,190);
//渲染(把当前上下文保存的所有路径都一次性渲染到view上面)
CGContextStrokePath(ctx);
//将栈顶的上下文出栈,替换当前的上下文
CGContextRestoreGState(ctx);
// 第2根线
CGContextMoveToPoint(ctx,10,70);
CGContextAddLineToPoint(ctx,220,290);
//渲染
CGContextStrokePath(ctx);
// CGContextDrawPath(ctx, kCGPathStroke); 渲染也可以用这种方式(前面参数为上下文,后面参数为枚举可确定渲染方式
}
当执行如下代码后,就会把内存中得存放图形上下文对象(中间)拷贝一份到栈当中(左图)
// 将ctx拷贝一份放到栈中
CGContextSaveGState(ctx);
当执行如下代码后内存状态为
// 设置绘图状态
CGContextSetLineWidth(ctx,10);
[[UIColorredColor] set];
CGContextSetLineCap(ctx,kCGLineCapRound);//设置画线的首位为圆状
//第1根线(这个路径暂时添加到上下文对象中)
CGContextMoveToPoint(ctx,50,50);
CGContextAddLineToPoint(ctx,120,190);
当执行下面代码后内存状态为
//渲染(把当前上下文保存的所有路径都一次性渲染到view上面)
CGContextStrokePath(ctx);
执行如下代码后内存状态为下图,也就是把保存在栈顶得上下文出栈替换掉第一根线的上下文)这个时候画第二根线的时候,其上下文状态就完全不受到第二根线的影响
//将栈顶的上下文出栈,替换当前的上下文
CGContextRestoreGState(ctx);
- [iOS]上下文的理解
- iOS绘图上下文的理解。
- 理解Session的上下文
- 上下文的理解
- 客户端的上下文理解
- 进程上下文与中断上下文的理解
- VC++ 设备上下文的理解
- 关于中断上下文的理解
- Flask上下文机制的理解
- Linux内核中进程上下文、中断上下文、原子上下文、用户上下文的理解
- ios UIKit的图形上下文
- ios-图片类型的上下文
- 个人对“进程上下文”和“中断上下文”的理解
- 对Linux内核进程上下文和中断上下文的理解
- 对Linux内核进程上下文和中断上下文的理解
- 对Linux内核进程上下文和中断上下文的理解
- Linux内核中进程上下文和中断上下文的理解
- Linux内核中进程上下文和中断上下文的理解
- Light oj 1138 - Trailing Zeroes (III) 【二分查找 && N!中末尾连续0的个数】
- 多线程 - 03.NSThread使用
- 03 java.lang.Boolean
- awaitTermination() shutdown()
- File:迭代读取文件夹下的文件或者文件夹
- [iOS]上下文的理解
- 数据库如何给含有外键的表中插入数据?
- 以前是行不通的,做事先做人
- HDOJ--2112--
- 大三了,大学也该搞点东西出来了!
- java获取本机的所有ip地址 包括IPV6
- Codeforces 474D Flowers 动态规划法
- Openstack kilo指南安装与实践(1)
- 黑马程序员——网络编程与设计模式