拥抱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,  100100);
 8     CGContextAddLineToPoint(con,  10025);
 9     CGContextSetLineWidth(con,  20);
10     CGContextStrokePath(con);
11 
12      //  绘制箭头部分
13      CGContextSetFillColorWithColor(con, [[UIColor redColor] CGColor]); 
14     CGContextMoveToPoint(con,  8025);
15     CGContextAddLineToPoint(con,  1000);
16     CGContextAddLineToPoint(con,  12025);
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:方法之后,视图会将自己标志为已更新,然后等待新的更新动作触发下一个更新周期。如果您的视图显示的是静态内容,则只需要在视图的可见性发生变化时进行响应就可以了,这种变化可能由滚动或其它视图是否被显示引起的。然而,如果您需要周期性地更新视图内容,就必须确定什么时候调用setNeedsDisplaysetNeedsDisplayInRect:方法来触发更新。举例来说,如果您需要每秒数次地更新内容,则可能要使用一个定时器。在响应用户交互或生成新的视图内容时,也可能需要更新视图。

 

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

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

 

欢迎加群互相学习,共同进步。QQ群:iOS: 58099570 | Android: 330987132 | Go:217696290 | Python:336880185 | 做人要厚道,转载请注明出处!
相关文章
|
XML 设计模式 前端开发
JavaFx-桌面应用开发利器(三)FXML和Scene Builder
本文首先简单介绍了Fxml和Scene Builder的基本知识,同时以eclipse为例,通过代码的形式说明如何进行Fxml的开发,最后使用SceneBuilder进行​应用快速开发。同时说明在使用eclipse中可能会遇到的一些问题以及解决办法​。
942 0
JavaFx-桌面应用开发利器(三)FXML和Scene Builder
|
前端开发 API 定位技术
|
vr&ar 开发工具 Android开发
扩大现实在Xamarin.Android与ARCore
现在,您已经有机会通过ARKit在Xamarin iOS应用程序中增加现实,现在是探索Google在Xamarin Android应用程序中对AR的影响力的时候了。新的ARCore SDK为增强现实功能提供API,例如运动跟踪,平面检测和光估计。
1127 0
|
Android开发 iOS开发
【Xamarin.Android】应用消费品
如果您正在构建一个需要购买多次内容的游戏或应用程序,你需要整合应用内购买消费品(IAPS)到您的应用程序。在我的前一篇IAP博文中,我教你设置你的应用程序为IAP交易基础, 添加IAP项目到谷歌应用商店或者iTunes连接,并介绍了Xamarin应用收费插件,大大简化了添加IAP应用程序的代码的过程。
1179 0
|
Java Android开发
《Android程序设计》一2.1 Android正在重塑客户端Java
本节书摘来自华章出版社《Android程序设计》一 书中的第2章,第2.1节,作者:G. Blake Meike, Masumi Nakamura,更多章节内容可以访问云栖社区“华章计算机”公众号查看。
1054 0
|
SQL .NET 数据库
Xamarin.Android开发实践(十三)
原文:Xamarin.Android开发实践(十三) Xamarin.Android之SQLite.NET ORM 一、前言 通过《Xamarin.Android之SQLiteOpenHelper》和《Xamarin.Android之ContentProvider》的 学习,我们已经掌握了如何使用特定于该平台的数据库操作。
922 0
|
Android开发 Java
Xamarin.Android开发实践(九)
原文:Xamarin.Android开发实践(九) Xamarin.Android之ActionBar与菜单 一、选项卡 如今很多应用都会使用碎片以便在同一个活动中能够显示多个不同的视图。在 Android 3.0 以上的版本中,我们已经可以使用ActionBar提供的Tab来实现这种效果,而不需要我们自己去实现碎片的切换。
1292 0