Core Graphics 101: 模版

来源:互联网 发布:华安股票交易软件 编辑:程序博客网 时间:2024/05/01 06:37

欢迎回到关于Core Graphics 101教程系列的另一篇教程!在这一系列教程中,我们将会结合相关的例子代码讲解有关Core Graphics 101的知识点!

在教程1,2和3中,我们讲解了如何使用Core Graphics技术,个性化定制一个table view的全过程!

在教程4中,我们将讲解如何使用Core Graphics技术去制作一个光滑的UIButton!

在这篇教程中,我们将展示如何创建一个在目前被许多app广泛使用的“grip”背景图案。您一定见过并且觉得它看起来很酷吧!

在教程中,你将巩固一些已经了解的关于绘制弧线和阴影的概念,并且你将会学到如何使用Core Graphics的内置绘画功能。

现在让我们开始吧!

开始

运行Xcode,选择“FileNew Project…”, 选择the View-based Application template,然后点击“Choose…”。命名工程为“CoolPattern”,然后保存。

接着点击左侧的Classes组,进入菜单栏选择“FileNew File…”,选择 iOS Cocoa Touch ClassObjective-C class,确保”Subclass of UIView”被选中,然后点下一步。命名文件为”CoolPatternView.m”,确保 ”Also create CoolPatternView.h”被选中,然后点击结束。

接下来打开CoolPatternView.m文件,然后添加以下代码到文件的顶部:

static inline double radians (double degrees) { return degrees * M_PI/180; }

这行代码只是一个用于转换角度值为弧度值的函数,在接下来还会用到。接着取消drawRect函数的注释,用以下的代码替换原来的内容:

CGContextRef context = UIGraphicsGetCurrentContext();CGColorRef redColor = [UIColor colorWithRed:1.0 green:0.0                                        blue:0.0 alpha:1.0].CGColor;CGContextSetFillColorWithColor(context, redColor);CGContextFillRect(context, self.bounds);

通常,这是我们用于填充整个view为红色的测试代码。

然后是时候来对CoolPatternViewController.xib文件进行设置了。思路是想要让grip稍微上下滚动,当我们放开对它的控制时,它会弹回中间位置,只是好玩而已。

我们接着打开ResourcesCoolPatternViewController.xib文件,注意到它有一个默认的页面,但是我们需要一个UIScrollView。删除XIB文件中的View,然后从右侧的控件库拖动一个UIScrollView控件到里面。

在Size Inspector(第三项)中,改变大小为320*480。 并且control键+鼠标点击从 File’s Owner拖动到Scroll View中,然后设置Scroll View作为view的outlet。

另外,在UIScrollView的Attributes Inspector中,需要选择”Always Scroll Vertically”。不然scrollView就默认不能滚动了,因为我们不会改变content view的大小。然后,拖动一个UIView到ScrollView中作为它的子层。

我们想让这个view显示出来,即使当用户把它滚动超过屏幕的高度时,因此在Size Inspector中,改变y offset为-400,然后设定高度为1280来设置一个很高的view,我们只能看到它的一部分。然后进入Identity Inspector, 改变view的class栏为CoolPatternView.

另外,你也可以拖动一个labe控件l到Cool Pattern View中作为它的子层,然后添加一些搞笑的文字到屏幕的中间。

就我个人的情况,我还设置了”# of Lines” label作为o(让它实现多行排列),添加了文字的字体大小,居中文本,设置了auto-sizing属性,以确保label在旋转过程中可以自适应,然后改变它的颜色为白色,纯属娱乐。

编译运行工程,如果一切运行正常,你会看到一个可以上下滚动,并且可以自动弹回的红色view(在拖动区域仍可看到红色):
Our grip view mocked up.

我们的目标

如果你看到一个放大后的grip效果,你将会了解到这只是一种简单的图案:
Grip Effect Zoomed

虚线区域展示了图案的重复部分。基本上有两个圆圈,一个在左上角,一个在向右的对角线上,每一个圆圈下面都有一个不明显的阴影。

基于目前我们在教程系列中讲解的内容,你已经知道了一种实现这种效果的方式:提供一个矩形去填充,计算出在x和y轴中需要重复这个图案的次数,然后用代码在一个循环结构中绘制圆圈或者阴影。

然而,在我们这样循环处理图案的时候,Core Graphics 有一个内置的API调用去绘制图案,有以下好处

a)更易编程, b)优化性能。让我们现在开始学习它吧!

使用Core Graphics绘制图案

用以下代码替换drawRect函数的内容:

CGContextRef context = UIGraphicsGetCurrentContext();CGColorRef bgColor = [UIColor colorWithHue:0 saturation:0 brightness:0.15 alpha:1.0].CGColor;CGContextSetFillColorWithColor(context, bgColor);CGContextFillRect(context, rect);static const CGPatternCallbacks callbacks = { 0, &MyDrawColoredPattern, NULL };CGContextSaveGState(context);CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern(NULL);CGContextSetFillColorSpace(context, patternSpace);CGColorSpaceRelease(patternSpace);CGPatternRef pattern = CGPatternCreate(NULL,                                       rect,                                       CGAffineTransformIdentity,                                       24,                                       24,                                       kCGPatternTilingConstantSpacing,                                       true,                                       &callbacks);CGFloat alpha = 1.0;CGContextSetFillPattern(context, pattern, &alpha);CGPatternRelease(pattern);CGContextFillRect(context, self.bounds);CGContextRestoreGState(context);

这个方法首先用背景颜色填充了整个矩形。然后,引入使用一个CGPatternCallbacks结构,该结构定义如下:

struct CGPatternCallbacks {   unsigned int version;   CGPatternDrawPatternCallback drawPattern;   CGPatternReleaseInfoCallback releaseInfo;};typedef struct CGPatternCallbacks CGPatternCallbacks;

所以基本上,我们传递了一个指向这个函数的指针o给这个version,用于绘制这个图案(接下来我们会实现这个函数),传递NULL给一个当图案绘制完成时调用的函数(然而我们并不需要它)。接下来,函数给图案创建了一个新的颜色区域,然后把原来的颜色填充区域设置给这个颜色区域。

下一行代码是最重要的部分,创建图案对象。这里它设定了图案绘制的界限(这里使用24*24像素点阵),图案方块之间留有空白(在这里每块使用24个像素点),使用了我们之前设计的回调结构引用,还有一些其他参数。接下来它把填充图案设置到图案对象中(而不是填充颜色),然后填充了矩形。

现在让我们写一个 ”MyDrawColoredPattern”回调函数用于绘制图案。将以下函数放到drawRect:方法上面:

void MyDrawColoredPattern (void *info, CGContextRef context) {     CGColorRef dotColor = [UIColor colorWithHue:0 saturation:0 brightness:0.07 alpha:1.0].CGColor;    CGColorRef shadowColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:0.1].CGColor;     CGContextSetFillColorWithColor(context, dotColor);    CGContextSetShadowWithColor(context, CGSizeMake(0, 1), 1, shadowColor);    CGContextAddArc(context, 3, 3, 4, 0, radians(360), 0);    CGContextFillPath(context);    CGContextAddArc(context, 16, 16, 4, 0, radians(360), 0);    CGContextFillPath(context)}

这个函数设定了两种颜色- 几乎为黑色的点,还有0.1 alpha值的白色阴影。该函数将第一种颜色设为填充颜色,第二种颜色作为阴影颜色(将下面的填充路线设定为一个像素点)。

然后使用AddArc函数(一个圆就是一个360度的弧线!)绘制了两个圆圈,然后把轨迹填充上颜色,一个圆在向右的对角线上。信不信由你,就这么简单!编译运行你的代码,你现在应该可以看到一个很酷的grip效果!

Finished Grip Effect with Core Graphics Patterns

Core Graphics 模版和性能

就如之前提到过的,Core Graphics模版的效率很高。

  1. 使用模版,就像上面一样
  2. 使用UIImage对象作为图案
  3. 使用多个Core Graphics调用在循环结构中绘制图案

我另外写了一些代码来记录每个drawRect方法调用的时间(UIImage版本包括了加载图片的时间)。以下是我的设备的测试结果:
Core Graphics Patterns Performance Comparison

不错!使用Core Graphics的好处在于如果你的模版变得越来越复杂(比如绘制更多的形状),模版的绘制应该仍然运作良好,因为绘制代码只被调用一次,然后被重复使用。

更新:就如cmar在以下的讨论中指出的,如果你使用 [UIColor colorWithPatternImage:...],你可以获得直接针对Core Graphics模版的可比较的测试结果。

所以如果你像这样需要在工程中重复使用的效果,你可以考虑使用Core Graphics模版(或者 [UIColor colorWithPatternImage])!

Where To Go From Here?

现在可以做什么?

这里是我们开发的包含了所有代码的例子程序。它同时包括了可以重新使用UIImage或者一个绘制循环结构来创建图案模版的测试代码,如果你也想试试的话,可以考虑使用。

这篇教程是Core Graphics101教程系列的终结篇。到目前为止,你应该对Core Graphics的基础有了比较牢固的掌握,并且可以在你自己的工程里面很好的使用!

如果你对Core Graphics感兴趣,你可以考虑学习动画。你可以从 如何使用UIView Animation的教程开始学习!