(四十八)Quartz2D引擎进阶
图形上下文栈:
应用,修改过上下文后,下一次画会在这个基础上进行,如果清空状态,需要上下文栈。
可以先把原来的上下文保存起来,然后恢复:
- (void)drawRect:(CGRect)rect { CGContextRef ref = UIGraphicsGetCurrentContext(); // 保存上下文
CGContextSaveGState(ref); CGContextMoveToPoint(ref, 100, 100);
CGContextAddLineToPoint(ref, 200, 200);
[[UIColor redColor] set];
CGContextSetLineCap(ref, kCGLineCapRound);
CGContextSetLineWidth(ref, 5);
CGContextStrokePath(ref); // 恢复上下文
CGContextRestoreGState(ref); CGContextMoveToPoint(ref, 250, 200);
CGContextAddLineToPoint(ref, 100, 180);
CGContextStrokePath(ref); }
在CGContextRef中有一个专门的空间用于保存上下文的状态,在其内部也有一个区域会把要画的东西先画一遍。
CGContextSaveGState是将ctx拷贝一份,放到栈中,Restore则是出栈。
Tip:CorePlot已经封装好了各种函数图。
矩阵操作:
先设置状态,再画才有作用:注意角度转弧度的时候除以180.0。
第一个是改变缩放比例,第二个是跳转转角。
CGContextScaleCTM(ctx, x_scale, y_scale);
CGContextRotateCTM(ctx, angle / 180.0 * M_PI_2);
图片的裁剪:
先在图像后面画一个形状,然后调用裁剪方法,最后再显示图片,就可以生成裁剪后的图片:
CGContextRef ctx = UIGraphicsGetCurrentContext(); CGContextAddEllipseInRect(ctx, CGRectMake(0, 0, 50, 50)); CGContextClip(ctx); CGContextFillPath(ctx); UIImage *image = [UIImage imageNamed:@"head"]; [image drawInRect:CGRectMake(0, 0, 50, 50)];
注意是先画一个圆,然后在圆心处放一个与圆的外接正方形重合的图片,这样就可以实现圆型裁剪。
注意先添加图形,再执行裁剪,再显示图形,最后显示图片。
刷帧的方法:多次调用绘图函数
注意drawRect只能由系统调用,手动调用无法获得上下文。
调用view的setNeedsDisplay可以让系统调用。
Tip:如果视图没有改变,调用这个方法仍然会重绘。
Tip:在drawRect方法中调用setNeedsDisplay不会引起死循环。
Tip:从storyboard或者xib初始化完成后会调用awakeFromNib,可以在这里做一些初始化的效果,例如定时器。
Tip:1s以上的使用NSTimer,对于高速刷帧,应该使用CADisplayLink方法。
[CADisplayLink displayLinkWithTarget: ... selector: ... ],用link指针指向它。
添加到消息循环的方法:[link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSdefaultRunLoop];
上下文显示到iOS手机屏幕,是通过Layer方式显示的。
Window指的是显示在Mac电脑屏幕上。
通过UIKit也可以调用Quarz2D:不需要主动传上下文。
UIRectFill方法可以画矩形,并且不需要传上下文。
通过创建路径的方式来绘图(涉及到内存管理):
实际上,直接使用ctx也是自动创建一个path,下面的过程通过path来绘图:即使是ARC,也需要使用release。
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 1.创建路径
CGMutablePathRef path = CGPathCreateMutable();
// 2.拼接路径
CGPathMoveToPoint(path, NULL, 0, 0);
CGPathAddLineToPoint(path, NULL, 100, 100);
// 3.添加路径
CGContextAddPath(ctx, path);
// 4.渲染
CGContextStrokePath(ctx);
// 5.释放path
CGPathRelease(path);
注意ColorSpace也是需要释放的。都有相应的Release函数(C语言方式)。
有一个统一的方法,CFRelease,可以释放任何对象。
(四十八)Quartz2D引擎进阶的更多相关文章
- NeHe OpenGL教程 第四十八课:轨迹球
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
- SQL注入之Sqli-labs系列第四十七关,第四十八关,第四十九关(ORDER BY注入)
0x1 源码区别点 将id变为字符型:$sql = "SELECT * FROM users ORDER BY '$id'"; 0x2实例测试 (1)and rand相结合的方式 ...
- 《手把手教你》系列技巧篇(四十八)-java+ selenium自动化测试-判断元素是否可操作(详解教程)
1.简介 webdriver有三种判断元素状态的方法,分别是isEnabled,isSelected 和 isDisplayed,其中isSelected在前面的内容中已经简单的介绍了,isSelec ...
- 第四十八个知识点:TPM的目的和使用方法
第四十八个知识点:TPM的目的和使用方法 在检查TPM目的之前,值得去尝试理解TPM设计出来的目的是为了克服什么样的问题.真正的问题是信任.信任什么?首先内存和软件运行在电脑上.这些东西能直接的通过操 ...
- abp(net core)+easyui+efcore实现仓储管理系统——入库管理之十二(四十八)
abp(net core)+easyui+efcore实现仓储管理系统目录 abp(net core)+easyui+efcore实现仓储管理系统——ABP总体介绍(一) abp(net core)+ ...
- Unity 游戏框架搭建 2019 (四十八/四十九) MonoBehaviourSimplify 中的消息策略完善&关于发送事件的简单封装
MonoBehaviourSimplify 中的消息策略完善 在上一篇,笔者说,MonoBehaviourSimplify 中的消息策略还有一些小问题.我们在这篇试着解决一下. 先贴出来代码: usi ...
- Python学习(四十二)—— Djago-model进阶
一.QuerySet 可切片 使用Python 的切片语法来限制查询集记录的数目 .它等同于SQL 的LIMIT 和OFFSET 子句. Entry.objects.all()[:5] # (LIMI ...
- C#编程(四十八)----------列表
C#中的List C#中deList怎么样?List<T>类是ArrayList类的泛型等效类,该类使用大小可按需动态增长的数组实现List<T>泛型接口. 泛型的好处:它为使 ...
- Jmeter(四十八)_动态线程分析HTML测试报告
概述 jmeterGUI模式下,性能测试的结果往往误差很大,因为GUI本身就会消耗一部分资源.所以我们常常用命令行去跑性能脚本,得出结果 同时,jmeter在命令行下还可以生成多维度的测试报告,里面包 ...
随机推荐
- leetcode刷题笔记08 字符串转整数 (atoi)
题目描述 实现 atoi,将字符串转为整数. 在找到第一个非空字符之前,需要移除掉字符串中的空格字符.如果第一个非空字符是正号或负号,选取该符号,并将其与后面尽可能多的连续的数字组合起来,这部分字符即 ...
- 牛客网编程练习之PAT乙级(Basic Level):1041 说反话
直接分隔取反即可 AC代码: import java.util.Scanner; /** * @author CC11001100 */ public class Main { public stat ...
- 小白到大神,Python 密集知识点汇总
Python 基础 1. 变量 你可以把变量想象成一个用来存储值的单词.我们看个例子. Python 中定义一个变量并为它赋值是很容易的.假如你想存储数字 1 到变量 "one" ...
- 20160216.CCPP体系详解(0026天)
程序片段(01):01.MemCpy.c 内容概要:内存拷贝 #include <stdio.h> #include <stdlib.h> #include <memor ...
- Programming In Scala笔记-第十六章、Scala中的List
本章主要分析Scala中List的用法,List上可进行的操作,以及需要注意的地方. 一.List字面量 首先看几个List的示例. val fruit = List("apples&quo ...
- [图论]最大流问题(Maximum flow)的定义
首先定义网络(network)N =(V,E), V表示顶点(Vertices)集合, E表示边(Edges)集合. s,t是V中的两个顶点,分别表示网络N中的源点(source)和汇点(sink). ...
- 剑指Offer——知识点储备-操作系统基础
剑指Offer--知识点储备-操作系统基础 操作系统 操作系统什么情况下会出现死锁? 产生死锁的必要条件 (1)互斥条件:即某个资源在一段时间内只能由一个进程占有,不能同时被两个或两个以上的进程占有, ...
- Dynamics CRM2016 Web API之Use custom FetchXML
CRM2016中新增的web api支持fetch xml了,之前使用FetchXML的场景是在后天代码中通过组织服务的retrieve multiple方法,但实际的应用效果有多大,还需要在实际的项 ...
- ZAB协议
zookeeper依赖zab协议来实现分布式数据一致性.基于该协议,zookeeper实现了一种主备模式的系统架构来保持ZooKeeper为高可用的一致性协调框架,自然的ZooKeeper也有着一致性 ...
- EJB_开发单表映射的实体bean
开发单表映射的实体bean 实体bean 它属于java持久化规范(JPA)里的技术,实体bean通过元数据在Javabean和数据库表之间建立起映射关系,然后Java程序员就可以随心所欲的使用面向对 ...