拥抱Core Graphics吧!

简介:

Core Graphics用于处理本地2D向量渲染和图片渲染。其中满是名称相近,让人郁闷的C接口。

对于在iOS上编程有一段时间的人来说有别的方法也会尽量避免使用这些C函数。

毕竟直接用xCode已有控件的话,只要拖一拖,然后少许的代码就可以做出某些效果,何必

自找苦吃?!但是Core Graphics有一个很大的优点:快! ps,我不是说要重复找轮子。

 

绘制在drawRect:方法中进行

当一个View需要绘制的时候,drawRect:方法会被调用。在这个方法中Core Graphics就会发挥作用,

你指定的区域会被重新绘制。但是你没法直接绘制UIView,而是继承UIView并自己实现drawRect:这个方法来进行绘制。 

 

找到绘制的上下文 

在绘制先需要保证绘制所在的上下文是在当前的View中。当前上下文使用UIGraphicsGetCurrentContext获得。

对于当前上下文,可以理解为Core Graphics对于当前所操作View的绘制操作一个指针,跟踪了全部的绘制操作。在C库中很多。

相当于面向对象编程语言中一个类的self指针。示例:

1 - ( void)drawRect:(CGRect)rect {
2     CGContextRef ctx = UIGraphicsGetCurrentContext();
3      //  绘制操作

4 }

在之后的代码里就可以用ctx来表示当前上下文。

 

绘制

绘制UIImage可以非常的简单,如:

1 - ( void)drawRect:(CGRect)rect {
2     CGContextRef ctx = UIGraphicsGetCurrentContext();
3     UIImage *img = [UIImage imageNamed: @" MyImage.png "];
4     [img drawInRect:rect];

5 }

 

画线

用Core Graphics画线和平时用笔画线的逻辑是一样的。先找到起始点,放下画笔,然后给画笔一系列的指令告诉它之后

往哪里画。每往下画一段都以上一段的终点为起点。用函数CGContextMoveToPoint把画笔移动到起始点。然后用函数

CGContextAddLineToPoint指定线条的终点,并在这两点之间画线。其他,还可以指定线条的颜色等。下面用具体的代码

来说明。代码:

复制代码
 1 - ( void)drawRect:(CGRect)rect
 2 {
 3      //  获取当前绘图上下文
 4      CGContextRef con = UIGraphicsGetCurrentContext();
 5 
 6      //  绘制箭杆部分
 7      CGContextMoveToPoint(con,  100,  100);
 8     CGContextAddLineToPoint(con,  100,  25);
 9     CGContextSetLineWidth(con,  20);
10     CGContextStrokePath(con);
11 
12      //  绘制箭头部分
13      CGContextSetFillColorWithColor(con, [[UIColor redColor] CGColor]); 
14     CGContextMoveToPoint(con,  80,  25);
15     CGContextAddLineToPoint(con,  100,  0);
16     CGContextAddLineToPoint(con,  120,  25);
17     CGContextFillPath(con);
复制代码

18 } 

最后结果,如图: 

 

 

 绘制长方形

 绘制是用CGRect变量指定位置和长,宽值。然后把该变量作为参数传给函数CGContextAddRect

复制代码
 1 - ( void)drawRect:(CGRect)rect {
 2 
 3         CGContextRef context = UIGraphicsGetCurrentContext();
 4 
 5         CGContextSetLineWidth(context,  2.0);
 6 
 7         CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
 8 
 9         CGRect rectangle = CGRectMake( 60, 170, 200, 80);
10 
11         CGContextAddRect(context, rectangle);
12 
13         CGContextStrokePath(context);
复制代码

14 } 

效果如下: 

 

绘制上下文状态保存 

从上面绘制的例子中可以看出。即使只是简单的画一条线也需要调好几个函数来设置这条线的

颜色、宽度,沿着哪条路径绘制等属性。 Core Graphics会保存这些属性在其内部的栈中。这个绘制状态就好比是一直笔,

你可以换笔头,颜色来画出不同的效果。但是如果你忘记把所有的东西换回去,那么下次再画出来的效果难保不会出乎意料。

 

函数CGContextSaveGState和函数CGContextRestoreGState专门用来处理绘制状态。CGContextSaveGState函数

就相当于给你当前的绘制状态打了个书签,之后你可以任意修改你想要修改的属性。然后可以用函数CGContextRestoreGState来重置绘制状态,

回到打了书签的地方。这两个函数必须要配对使用! 否则的话,绘制状态就全部乱了,要不绘出来的不是你想要,要不绘制都无法继续。

复制代码
 1 - ( void)drawRect:(CGRect)rect
 2 {
 3     CGContextRef ctx = UIGraphicsGetCurrentContext();
 4     
 5      //  设置属性
 6      CGColorRef whiteColor = [UIColor whiteColor].CGColor;
 7     CGColorRef lightColor = _lightColor.CGColor;
 8     CGColorRef darkColor = _darkColor.CGColor;
 9     CGColorRef shadowColor = [UIColor colorWithRed:.2f green:.2f blue:.2f alpha:.5f].CGColor;
10     
11     CGContextSetFillColorWithColor(ctx, whiteColor);
12     CGContextFillRect(ctx, _paperRect);
13     
14      //  保存绘制属性
15      CGContextSaveGState(ctx);
16     
17      //  绘制。。。
18      
19       //  还原绘制属性
20      CGContextRestoreGState(ctx);
复制代码

21 }

 

View的重绘

苹果文档的一段话说的非常清楚: 

任何时候,当视图的一部分需要重画时,UIView对象内置的描画代码就会调用其drawRect:方法,并向它传入一个包含需要重画的视图区域的矩形。您需要在定制视图子类中重载这个方法,并在这个方法中描画视图的内容。在首次描画视图时,UIView传递给drawRect:方法的矩形包含视图的全部可见区域。但在随后的调用中,该矩形只代表实际需要被描画的部分。触发视图更新的动作有如下几种:

  • 对遮挡您的视图的其它视图进行移动或删除操作。

  • 将视图的hidden属性声明设置为NO,使其从隐藏状态变为可见。

  • 将视图滚出屏幕,然后再重新回到屏幕上。

  • 显式调用视图的setNeedsDisplay或者setNeedsDisplayInRect:方法。

在调用drawRect:方法之后,视图会将自己标志为已更新,然后等待新的更新动作触发下一个更新周期。如果您的视图显示的是静态内容,则只需要在视图的可见性发生变化时进行响应就可以了,这种变化可能由滚动或其它视图是否被显示引起的。然而,如果您需要周期性地更新视图内容,就必须确定什么时候调用setNeedsDisplay或setNeedsDisplayInRect:方法来触发更新。举例来说,如果您需要每秒数次地更新内容,则可能要使用一个定时器。在响应用户交互或生成新的视图内容时,也可能需要更新视图。

 

最后,暂时先总结这么多,后面会陆续深入讲解这部分内容。只要参考着苹果的官方文档多练。在实际开发中多用。你自然会对Core Graphics驾轻就熟。

希望此文对你有所帮助。谢谢! 

 

欢迎加群互相学习,共同进步。QQ群:iOS: 58099570 | Android: 330987132 | Go:217696290 | Python:336880185 | 做人要厚道,转载请注明出处!
相关文章
|
测试技术 网络架构
【技术干货连载 一】业务经过WAF HTTP 400问题排查
教你如何排查和解决业务经过WAF 七层代理HTTP 400问题原因?
977 1
|
缓存 API 开发者
魔搭社区牵手FastChat&vLLM,打造极致LLM模型部署体验
FastChat是一个开放平台,用于训练、服务和评估基于LLM的ChatBot。
|
SQL 数据库
使用PD(PowerDesigner)图如何快速生成创建数据库表的SQL脚本并生成表在数据库
使用PD(PowerDesigner)图如何快速生成创建数据库表的SQL脚本并生成表在数据库
1572 0
使用PD(PowerDesigner)图如何快速生成创建数据库表的SQL脚本并生成表在数据库
|
11月前
|
人工智能 算法 新能源
2025 全球GEO优化行业年度观察:市场格局与技术革新双轮驱动
2025年,GEO(生成式引擎优化)从营销工具升级为品牌数字化生存刚需。依托多模态大模型与AI搜索变革,即搜AI、边鱼科技等领军企业推动技术标准落地,助力品牌抢占AI信源主权。国内市场规模达480亿元,跨境增长达93.1%。GEO正重塑全球流量格局,成为企业降本增效、出海突围的核心引擎。
|
人工智能 搜索推荐 API
数字化美学的基石:集成 AI 人脸识别API 的技术实践与深度分析
在2026年数字化零售趋势下,我们推出AI Face Analyzer API,通过人脸识别70+面部特征,实现脸型、五官、年龄等多维度分析,助力品牌打造个性化美妆护肤方案。
541 0
|
11月前
|
机器学习/深度学习 人工智能 安全
大模型伦理与公平性术语解释
简介:大语言模型中的偏见源于训练数据,可能导致性别、种族等歧视,影响公平性。公平性要求模型无差别对待各群体,需通过数据与算法去偏。可解释性助力理解模型决策,提升信任与改进。安全对齐防止有害输出,人类对齐确保价值观一致,隐私保护防范数据泄露。这些是构建负责任AI的核心要素,需技术、伦理与法规协同推进。(238字)
|
Java 编译器 API
如何在 Java 中避免使用迭代器
在Java中,为了避免使用迭代器,可以采用foreach循环来遍历集合或数组,简化代码,提高可读性。此外,Java 8引入的Stream API提供了更强大的功能,如filter、map等方法,能够以函数式编程风格处理数据,进一步减少对传统迭代器的依赖。
416 7
|
C语言
C语言---函数---知识点总结(三)------函数的返回值类型
C语言---函数---知识点总结(三)------函数的返回值类型
|
JSON 安全 数据处理
淘宝开放平台订单接口的详细使用教程
本教程详细介绍如何使用淘宝开放平台订单接口,涵盖注册申请、环境准备、接口调用及数据处理等步骤。首先,需注册开发者账号并创建应用,获取必要的权限与密钥。接着,选择合适的编程语言和工具,安装必要库,配置开发环境。然后,了解并调用相关订单接口,设置请求参数,生成签名,发送请求并处理响应。最后,进行数据处理和错误处理,确保程序稳定可靠。
|
SQL 存储 调度