Quartz Core 图层编程

\

Quartz Core 图层编程

一、添加 Quartz Core 框架

要使用 Quartz Core 框架,你需要将其添加到你的工程中 。 然后  #import <Quartz Core/QuartzCore.h>

二、认识图层

对 ps 有所了解的人都知道图层的概念,在这里也一样。在PS中一张图片至少得有一个图层,一个或多个图层的叠加构成了一张位图。我们这里一个或多个图层的叠加的构成了UIView(或其派生类)对象。看过我关于 UIView 文章的人可能会有疑问:UIView 和图层没啥区别啊?NO,还是有区别的,图层是有弹性的,你可以操纵图层,使 UIView 有各种效果,比如三维效果,形变等等。

要访问一个图层,需要读取 UIview 的 layer 属性。

[java] view plaincopyprint?

  1. CALayer* layer = self.view.layer;

所有派生自UIView 的对象,都会继承这一属性,这意味着你可以对导航栏、表格、文本框以及其他许多类型的视图类,进行变换、缩放、旋转、甚至加入动画。

有人又有疑问了,上面的代码我们只读取了一个 layer 假如一个UIView 有多个图层呢? 不错 UIView 确实只有一个layer 属性,但是layer 是可以叠加的,layer 可以叠加在 layer 上面,所以这个layer 就相当于是一块底板,我们可以在这块地板上叠加一些透明胶片(子图层),叠加在一起之后就构成了一个组合图像。

三、图层的层次结构

图层有很多通用的方法和属性,来操作子图层和执行绘制操作。这些方法允许你将许多单个图层叠加在一起,来绘制一个组合的屏幕图像。

一个图层可以有许多个子图层。在最终绘制屏幕时,子图层可以被排列后固定在一起。这可以参考赛车游戏中的图层。游戏可能有几个图层组成:一个绘制背景、一个绘制角色、一个绘制地图显示器。你可能会为每个图层准备一个专门的UIView类,并另外用一个UIView类来整合游戏画面:

[java] view plaincopyprint?

  1. UIView* gameView = [[UIView alloc]initWithFrame:[[UIScreen mainScreen]applicationFrame] ];
  2. UIView* backgroundView = [[UIView alloc]initWithFrame:[[UIScreen mainScreen]applicationFrame]];
  3. UIView* roleView= [[UIView alloc]initWithFrame:CGRectMake(0.0, 0.0, 100.0, 200.0)];
  4. UIView* mapView = [[UIView alloc]initWithFrame:CGRectMake(200.0, 0.0, 100.0, 100.0)];
  5. //通过CALayer 类的addSublayer 方法,你可以将3个UIView 类的图层全都与 gameView 对象链接在一起:
  6. CALayer* gameLayer = gameView.layer;
  7. [gameLayer addSublayer:backgroundView.layer];
  8. [gameLayer addSublayer:roleView.layer];
  9. [gameLayer addSublayer:mapView.layer];

当gameView 对象显示在屏幕上的时候,3个子图层被合并在一起绘制出来。每个类单独绘制他自己的图层,但当游戏图层被显示出来的时候,3个图层就全都融合在一起了。

gameView不是唯一能够添加子图层的图层。子图层也可以添加自己的子图层,并且可以构建一个完整的图层层次结构。例如你的游戏可能会在 mapView图层中再构加入一个图层,用来显示map的一部分内容,比如剩余里程数。

[java] view plaincopyprint?

  1. UILabel* lastDistance = [[UILabel alloc]initWithFrame:CGRectMake(0.0, 0.0, 20.0, 20.0)];
  2. [mapView.layer addSublayer:lastDistance.layer];

此外,通过设置图层的position属性,你还可以不用改变图层的大小就对其位置进行调整。这个属性接受一个CGPoint 结构体,来定位图层在屏幕上的偏移位置。与frame 属性不同,position 属性指定的是图层的重点,而不是左上角:

[java] view plaincopyprint?

  1. CGPoint lastDistancePosition = CGPointMake(100.0, 100.0);
  2. lastDistance.layer.position = lastDistancePosition;

四、布局与显示

除了添加子图层之外,CALayer 类还提供了很多不同的方法,可以来插入、调整和移除子图层。

当你用 addSublayer 来添加一个子图层时,他会被添加到图层层次结构的顶层,所以他会显示在现有所有子图层的最前面。用一组名为 insertSublayer 的替代方法,你可以将新视图插入现有的图层之间。

用atIndex 参数,可以将一个图层插入到指定的下标位置:

[java] view plaincopyprint?

  1. [gamelayer insertSublayer:mapView.layer atIndex:1];

要将一个图层插入到另一个图层的上面或者下面,可以加上 avove 或 below 参数:

[java] view plaincopyprint?

  1. [ gamelayer insertSublayer:mapView.layer below:backgroundView.layer];
  2. [ gamelayer insertSublayer:mapView.layer above:roleView.layer];

调用子图层的 removeFromSuperlayer 方法,可以将图层从他的父图层中删除:

[java] view plaincopyprint?

  1. [ mapView.layer removeFromSuperlayer];

要用另外一个图层代替现有的一个子图层,可以用replaceSublayer 方法:

[java] view plaincopyprint?

  1. [ gamelayer replaceSublayer:backgroundView.layer with:newBackgroundView.layer ];

要将子图层保留在图层栈中,但是又想让他在显示的时候不可见,可以设置图层的 hidden 属性。你可以用下面的代码来切换map 显示,而不必真的把图层去掉:

[java] view plaincopyprint?

  1. - (void) Togglemap{
  2. mapView.layer.hidden = (mapView.layer.hidden == NO)?YES:NO;
  3. }

五、绘制

在更新一个图层时,变化不是立刻被绘制在屏幕上的。这样你就可以偷偷地对图层做很多写操作而不会被展示给用户,直到所有的操作全部结束为止。当图层准备好可以进行重画时,就调用图层的 setNeedsDisplay  方法:

[java] view plaincopyprint?

  1. [ gamelayer setNeedsDisplsy ];

有些时候,可能仅仅不要重画整个图层的部分内容。重新绘制整个屏幕会令程序性能低下。用 setNeedsDisplayInRect 方法,可以只重画需要更新的部分屏幕,这个方法需要一个表示更新区域的CGRect 结构体作为参数:

[java] view plaincopyprint?

  1. CGRect mapViewFrame  =CGRectMake(150.0,150,75.0,75.0);
  2. [ gameLayer setNeedsDisplayInRect:mapViewFrame  ];

如果你在使用 Core Graphics 框架进行绘制,可以直接在一个 Core Graphics 上下文中绘制。使用 renderInContext 方法可以做到这一点:

[java] view plaincopyprint?

  1. CGContextRef myCGContext = UIGraphicsGetCurrentContext();
  2. [ gamelayer renderInContext:myCGContext ];

六、变换

要为图层加上一个三维变换或者仿射变换,可以分别设置图层的 transform 或 affineTransform 属性。

[java] view plaincopyprint?

  1. roleview.layer.transform = CATransform3DMakeScale( -1.0,-1.0,1.0);
  2. CGAffineTransform transform = CGAffineTransformMakeRotation(45.0);
  3. backgroundView.layer.affineTransform =transform ;

七、图层动画

Quartz Core 的能力远远不止一个简单的画板式图层。他可以将一个二维物体变换为一个令人瞠目结舌的三维纹理,用于创建NB的转场动画。

我之前写过一篇介绍转场动画的文章,那是一种在不同 UIView 对象之间进行过度的手段。你可以直接将转场动画用于图层或子图层。动画可以作为 CAtransition 对象创建出来。

图层转场增强了现有的 CATransition 类,为其提供了一种方法,能用Quartz Core 的动画引擎来添加动画。这令开发者可以利用Quartz Core提供的三维功能,而不必对代码做大的改动。当图层被动画使,一个 CATransition 或CAAnimation 对象会被附加在图层上。然后图层会调用Quartz Core,分支出一个新线程,负责动画的全部图形处理工作。开发者秩序加入期望的动画,就可以提升一个现有图层的功能。用下面的例子代码,可以创建一个转场:

[java] view plaincopyprint?

  1. CATransition* animation = [[CATransition alloc]init];
  2. animation.duration =1.0;
  3. animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
  4. animation.type = kCATransitionPush;
  5. animation.subtype = kCATransitionFromRight;

警告:到目前为止,恶心的的苹果允许用户创建的转场类型仍然极其有限。Quartz Core 框架内部还支持相当多的其他转场效果,例如自然翻页和缩放转场等,但是受到限制,只能有苹果自己的应用程序使用。(恶心吧)

通过创建一个CABasicAnimation 对象,你就可以创建出一个动画。下面的例子创建了一个动画,将图层旋转了整整360度:

[java] view plaincopyprint?

  1. CABasicAnimation *animation = [CABasicAnimation  animationWithKeyPath:@"transform"];
  2. animation.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(3.1415, 0, 0, 1.0)];
  3. animation.duration =3.0;
  4. animation.cumulative =YES;
  5. animation.repeatCount=2;

创建好之后,你可以直接将动画或者转场应用到一个图层上:

[java] view plaincopyprint?

  1. [mapView.layer addAnimation:animation forKey:@"animation"];

八、图层变换

Quartz Core 的渲染能力可以像三维一样对二维图像进行任意操纵。一个图像可以在x-y-z 三维轴上进行任意角度旋转、缩放和扭曲。CATransform3D 函数族是苹果的Cover Flow 技术 以及 iPhone 上使用的其他美观特效的幕后力量。iPhone 支持包括缩放、旋转、仿射、平移等。

变换实在单独的图层上执行的,因此多个变换可以在一个图层表面上同时进行。Quartz Core 框架用 CATransform3D 对象来执行变换。这个对象作用于视图的图层,根据期望的三维设置对图层进行弯折或者其他操作。应用程序可以仍然将对象看作是二维的,但是当对象呈现给用户时,会遵从已经作用于图层之上的任何变换。下面的例子创建了一个变换,目的是对一个图层进行旋转:

[java] view plaincopyprint?

  1. CATransform3D myTransform;
  2. myTransform = CATransform3DMakeRotation(angle,x,y,z);

CATransform3DMakeRotation 函数创建了一个变换,对一个图形进行旋转,旋转角度angle 单位为弧度,轴为 x-y-z 。x-y-z 的值定义了轴上在各个方向上的度量(介于-1和+1之间)。在一个轴上赋予值,就会指示变换绕该轴进行旋转。可以把这些值看作是插在图像上的草棍。如果草棍是沿着 x 轴插进去的,那么图像将绕着草棍垂直旋转。你可以使用不同角度值作为轴,产生出更复杂的转动。不过对于大多数用途来说,用-1 和 +1 这两个值就够了。

要将一个图层绕水平轴转动(垂直转动)45度,可以使用下面的代码:

[java] view plaincopyprint?

  1. myTransform = CATransform3DMakeRotation(0.78,1.0,0.0,0.0);//0.78 是角度45度换成弧度得到的

要在水平方向上转动同样的角度,可以换成 y 轴指定一个值:

[java] view plaincopyprint?

  1. myTransform = CATransform3DMakeRotation(0.78,0.0,1.0,0.0);

你可以自己编写一个角度转弧度的函数:

[java] view plaincopyprint?

  1. double radians(float degrees){
  2. return (degrees*3.14159265)/180.0;
  3. }

当你创建的时候就调用这个函数:

[java] view plaincopyprint?

  1. myTransform = CATransform3DMakeRotation( radians(45.0),0.0,1.0,0.0);

变换创建完毕之后,就要作用于你要操纵的图层了。CALayer 对象提供了一个 transform属性,可以用来将变换附加到图层之上。图层将会执行任何赋予这个属性的变换:

[java] view plaincopyprint?

  1. roleView.layer.transform = myTransform;

当这个对象被显示出来时,会按照应用在他上面的变换进行显示。在你的代码里,还是会将这个对象作为一个二维物体来引用,但是他会根据变换来进行渲染。

Quartz Core 图层编程,布布扣,bubuko.com

时间: 2024-08-12 22:01:45

Quartz Core 图层编程的相关文章

学习ASP.NET Core Razor 编程系列五——Asp.Net Core Razor新建模板页面

学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET Core Razor 编程系列三——创建数据表及创建项目基本页面 学习ASP.NET Core Razor 编程系列四——Asp.Net Core Razor列表模板页面 上一篇文章中我们学习了列表页面的结构,@page与@model两个关键Razor指令,以及页面布局应该修改哪里.这一篇文章我们来

学习ASP.NET Core Razor 编程系列七——修改列表页面

学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET Core Razor 编程系列三——创建数据表及创建项目基本页面 学习ASP.NET Core Razor 编程系列四——Asp.Net Core Razor列表模板页面 学习ASP.NET Core Razor 编程系列五——Asp.Net Core Razor新建模板页面 学习ASP.NET C

学习ASP.NET Core Razor 编程系列九——增加查询功能

学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET Core Razor 编程系列三——创建数据表及创建项目基本页面 学习ASP.NET Core Razor 编程系列四——Asp.Net Core Razor列表模板页面 学习ASP.NET Core Razor 编程系列五——Asp.Net Core Razor新建模板页面 学习ASP.NET C

学习ASP.NET Core Razor 编程系列十——添加新字段

学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET Core Razor 编程系列三——创建数据表及创建项目基本页面 学习ASP.NET Core Razor 编程系列四——Asp.Net Core Razor列表模板页面 学习ASP.NET Core Razor 编程系列五——Asp.Net Core Razor新建模板页面 学习ASP.NET C

Core Animation编程指南

本文是<Core Animation Programming Guide>2013-01-28更新版本的译文.本文略去了原文中关于OS X平台上Core Animation相关内容.因为原文的类型属于编程指南,所以示例代码并不多,更多的是理论层面的探讨.所以译文中加入了大量的示例代码,以提高本文的可操作性.希望本文能够对你有所帮助. 本文由海水的味道翻译,转载请注明译者和出处,请勿用于商业用途! 关于Core Animation Core Animation是iOS与OS X平台上负责图形渲染

Quartz Core框架之CALayer

1.继承链:NSObject 2.创建一个layer (1)+ (instancetype)layer :创建和返回一个layer实例对象 (2)- (instancetype)init :返回一个初始化的calayer对象 (3)- (instancetype)initWithLayer:(id)layer :为一个视图对象初始化一个已经存在的layer对象,view.layer = layer 3.读取相关的layer 对象 (1)- (id)presentationLayer :返回一个复

.NET Core嵌入式编程开关量GPIO(控制2个灯泡交替闪烁)

一.在树莓派中安装.NET Core运行时 1.到微软的官方站点下载.NET Core运行时 下载地址 2.选择Linux 中的ARM32,如果不需要跑web,可以选择更精简的.NET Core Binaries ARM32. 借助xftp 把下载回来的压缩包送到树莓派里面. 3.把压缩包解压缩处理,并建立软连接,即可安装完成.NET Core sudo mkdir /usr/share/dotnet(新建文件夹) sudo tar -xvf dotnet-sdk-3.0.100-linux-a

Quartz Core框架之core animation

1.时间功能 (1)CFTimeIntervalCACurrentMediaTime ( void ); :返回当前的绝对时间 2.转换功能 (1)bool CATransform3DIsIdentity ( CATransform3D t ); :返回bool判断是不是单位形变 (2)bool CATransform3DEqualToTransform ( CATransform3D a, CATransform3D b ); :判断两个变形是否相等 (3)CATransform3D CATr

IOS用CGContextRef画各种图形(文字、圆、直线、弧线、矩形、扇形、椭圆、三角形、圆角矩形、贝塞尔曲线、图片)(转)

Graphics Context是图形上下文,可以将其理解为一块画布,我们可以在上面进行绘画操作,绘制完成后,将画布放到我们的view中显示即可,view看作是一个画框. 自己学习时实现的demo,希望对大家有帮助,具体的实现看代码,并有完美的注释解释,还有一些对我帮助的博文供大家参考.都在代码里面. 看一下demo效果图先: 自定义CustomView类,CustomView.h: [cpp]  view plain copy #import <UIKit/UIKit.h> #import