CALayer的简单使用

2024-05-31 06:58
文章标签 简单 使用 calayer

本文主要是介绍CALayer的简单使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原文地址:http://www.raywenderlich.com/2502/calayers-tutorial-for-ios-introduction-to-calayers-tutorial


如果你已经在iPhone上做过开发,你可能对UIView和它的子类-Button,text,slider等,非常熟悉。

但你可能不了解UIView是建立在CALayers之上的,至少我曾经有段时间不知道。
了解CALayers是有用的,因为你可以使用它们轻松地去创造一些纯视觉效果,它们对理解使用将在未来教程中讨论的Core Animation也很重要。
在CALayers的教程中,你将通过做创造一个层并实验它的效果的简单APP去学习基本的层的使用,在这个过程中,你将学到层是什么,一些能设置的纯属性和如何将图像和自定义内容放入层里。

这个层的教程假设你基本熟悉iPhone编程,如果你是新手,可以从如何创建一个简单的iPhone App开始。
让我们开始吧

什么是层?

层是表现一个在屏幕上的包含可视内容的矩形的简单类。
“等一下”,你可能说,“这是UIView的定义”,是这样的,但这儿有个把戏:每一个UIView包含一个用于绘制的根层,你可以使用下面的代码访问这个自动创造的层:(CALayer是UIView的根基)
CALayer  * myLayer  =  myView.layer;
CALayer类包含了很多可设置的影响外观显示的属性,例如:
层的尺寸和位置
层的背景颜色
层的内容(图像或者使用Core Graphics绘制的)
是否是圆角层
在层的边缘应用边框
更多内容
你可以使用这些属性去创造一些效果,例如你想拿一副图片,放在白色的边框,应用一个阴影效果,使其更为逼真,而不是拿出Photoshop或写一堆Core Graphicsdaima代码,你可以使用层的代码。
另外层的属性,多数是可以动画的,例如,你可以开始用圆角图片,点击按钮,有个动画效果,圆角变回直角,使用起来是非常方便简单的。
你可以直接使用层类,或者你可以使用一个 它的子类,例如CAGradientLayer, CATextLayer, CAShapeLayer,和其他。UIView默认的层类是CALayer类,这个是教程的重点。

开始

这儿去了解层的使用的最好方法是自己动手,所以启动Xcode,选择File\New Project,选择 iOS\Application\View-Based Application,点"Choose",起名工程"Layer
Fun",点保存(就是创建个测试Layer的工程)。
添加QuzatCore,做下列改动到LayerFunViewController.m:
[cpp]  view plain copy print ?
  1. // Import QuartzCore.h at the top of the file  
  2. #import <QuartzCore/QuartzCore.h>  
  3.    
  4. // Uncomment viewDidLoad and add the following lines  
  5. self.view.layer.backgroundColor = [UIColor orangeColor].CGColor;  
  6. self.view.layer.cornerRadius = 20.0;   
  7. self.view.layer.frame = CGRectInset(self.view.layer.frame, 20, 20);  


让我们一步一步回顾这些新东西
为了得到view的层,你可以使用self.view.layer,记住,你可以使用self.view获得view controller 的根视图,你一旦得到视图,你可以使用view.layer获得默认的层(自动创建的),默认层是一个CALayer的类(不是子类)。
下一步你设置层的背景色为橙色,注意背景色属性实际是CGColor类型,但可以使用CGColor属性从UIColor到CGColor转换。
下一步你设置圆角的弧度,设置的这个值是制造圆角的圆的半径,20是一个漂亮的圆角边缘。
最终,你使用CGRectInset的功能,收缩一点frame,方便看到效果。CGRectInset函数收缩X和Y的坐标,返回一个新的Frame。
编译执行你的代码,你可以在屏幕中央看到一个圆角橙色矩形。

层和子层

就像UIView可以有自视图,CALayers可以也可以用子层,你可以使用下面的代码创建一个新的层:
CALayer  * sublayer  =   [ CALayer layer ] ;
一旦你拥有一个层,你可以在上面设置任何你想要的属性,但是记住这儿有一个属性你一定要设置:它是frame(或者bounds/ position)。毕竟,层需要去知道它有多大(在什么位置),才能画出自己。当你完成了,你可以把新的层当作子层添加到另一个层中,通过下面的代码:
[ myLayer addSublayer : sublayer ] ;
好了,现在试着自己添加一个简单的子层到view的层中,添加下面的代码在viewDidLoad函数内之前添加代码的后面:
[cpp]  view plain copy print ?
  1. CALayer *sublayer = [CALayer layer];  
  2. sublayer.backgroundColor = [UIColor blueColor].CGColor;  
  3. sublayer.shadowOffset = CGSizeMake(0, 3);  
  4. sublayer.shadowRadius = 5.0;  
  5. sublayer.shadowColor = [UIColor blackColor].CGColor;  
  6. sublayer.shadowOpacity = 0.8;  
  7. sublayer.frame = CGRectMake(30, 30, 128, 192);   
  8. [self.view.layer addSublayer:sublayer];  

这创建了一个新的层,并且设置了一些属性,包括一些之前没设置过的阴影属性,你可以看到在层上设置阴影是多么简单,通过这样,可以用一点工作量完成令人惊奇的效果。(就是简单、方便、有效果)
在设置了这些属性,需要设置层的frame并且把它加到view的层中,记住这些坐标是相对于父层的frame(父层坐标体系的坐标)如果父层位于(20,20),子层设置偏移(30,30),子层在屏幕的位置将会是(50,50).
编译执行你的代码,你将看到一个蓝色子层在屏幕上。


设置层的图像内容

CALayers可以包含更多的内容除了纯颜色,它非常容易包含图片内容,例如:
先将一张名为“BattleMapSplashScreen.jpg”的图片包含进项目
然后添加以下代码:
[cpp]  view plain copy print ?
  1. sublayer.contents = (id) [UIImage imageNamed:@"BattleMapSplashScreen.jpg"].CGImage;  
  2. sublayer.borderColor = [UIColor blackColor].CGColor;   
  3. sublayer.borderWidth = 2.0;  


这里设置了内容为图片的层,并且使用边界的颜色和宽度设置了一圈黑色的边界,演示了它如何工作。
编译执行你的代码,你可以看到蓝色层的内容被图片替换调了。

圆角半径和图片内容的注意点

现在你可能想通过cornerRadius把图片也设置成圆角效果。
然而问题超过了咱们之前学的范围,如果你在层上设置了图片内容,图像将仍然画出圆角的边界(该属性起不了作用),你可以通过设置子层的masksToBounds为Yes,但如果你这样做,阴影效果将不会出现因为他们被盖掉了。

我找到一个创造两个层的方法,在外的层是有边框和阴影带颜色的层,里面的层包含圆角图像和设置mask,这样在外的层绘制阴影,在里的层包含图像。

试着使用下面的替换创建子层的代码:
[cpp]  view plain copy print ?
  1. CALayer *sublayer = [CALayer layer];  
  2. sublayer.backgroundColor = [UIColor blueColor].CGColor;  
  3. sublayer.shadowOffset = CGSizeMake(0, 3);  
  4. sublayer.shadowRadius = 5.0;  
  5. sublayer.shadowColor = [UIColor blackColor].CGColor;  
  6. sublayer.shadowOpacity = 0.8;  
  7. sublayer.frame = CGRectMake(30, 30, 128, 192);  
  8. sublayer.borderColor = [UIColor blackColor].CGColor;  
  9. sublayer.borderWidth = 2.0;  
  10. sublayer.cornerRadius = 10.0;  
  11. [self.view.layer addSublayer:sublayer];  
  12.    
  13. CALayer *imageLayer = [CALayer layer];  
  14. imageLayer.frame = sublayer.bounds;  
  15. imageLayer.cornerRadius = 10.0;  
  16. imageLayer.contents = (id) [UIImage imageNamed:@"BattleMapSplashScreen.jpg"].CGImage;  
  17. imageLayer.masksToBounds = YES;   
  18. [sublayer addSublayer:imageLayer];  
编译运行代码,现在你的图像将有圆角

层和自定义绘画内容

如果你想使用Core Graphics替代图片绘制自定义的层,也是很容易的。
方法是你设置一个类作为层的代理对象,这个类实现名为drawLayer:inContext的方法,里面包含你想绘制内容的Core Graphics代码。
让我们试着添加一个新的层,在里面画一个图案,你把层的代理指向view controller的对象,实现drawLayer:inContext的方法去画图案。
在你的viewDidLoad添加以下代码建立一个新层:
[cpp]  view plain copy print ?
  1. CALayer *customDrawn = [CALayer layer];  
  2. customDrawn.delegate = self;  
  3. customDrawn.backgroundColor = [UIColor greenColor].CGColor;  
  4. customDrawn.frame = CGRectMake(30, 250, 128, 40);  
  5. customDrawn.shadowOffset = CGSizeMake(0, 3);  
  6. customDrawn.shadowRadius = 5.0;  
  7. customDrawn.shadowColor = [UIColor blackColor].CGColor;  
  8. customDrawn.shadowOpacity = 0.8;  
  9. customDrawn.cornerRadius = 10.0;  
  10. customDrawn.borderColor = [UIColor blackColor].CGColor;  
  11. customDrawn.borderWidth = 2.0;  
  12. customDrawn.masksToBounds = YES;  
  13. [self.view.layer addSublayer:customDrawn];   
  14. [customDrawn setNeedsDisplay];  

这里的代码,大多数之前都出现过,就有两点是新的:
1 第一 把层的委托设置给self,这以为这个对象(self)将需要实现 drawLayer:inContext去绘制层的内容。
2 在添加层后,需要通过调用setNeedsDisplay通知层去刷新自己(并调用drawLayer:inContext),如果你忘记调用这个,drawLayer:inContext将不会被调用,图案将不出现。
接下来添加代码去实现drawLayer:inContext,如下:
 
[cpp] view plaincopyprint?
  1. void MyDrawColoredPattern (void *info, CGContextRef context) {  
  2.    
  3.     CGColorRef dotColor = [UIColor colorWithHue:0 saturation:0 brightness:0.07 alpha:1.0].CGColor;  
  4.     CGColorRef shadowColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:0.1].CGColor;  
  5.    
  6.     CGContextSetFillColorWithColor(context, dotColor);  
  7.     CGContextSetShadowWithColor(context, CGSizeMake(0, 1), 1, shadowColor);  
  8.    
  9.     CGContextAddArc(context, 3, 3, 4, 0, radians(360), 0);  
  10.     CGContextFillPath(context);  
  11.    
  12.     CGContextAddArc(context, 16, 16, 4, 0, radians(360), 0);  
  13.     CGContextFillPath(context);  
  14.    
  15. }  
  16.    
  17. - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)context {  
  18.    
  19.     CGColorRef bgColor = [UIColor colorWithHue:0.6 saturation:1.0 brightness:1.0 alpha:1.0].CGColor;  
  20.     CGContextSetFillColorWithColor(context, bgColor);  
  21.     CGContextFillRect(context, layer.bounds);  
  22.    
  23.     static const CGPatternCallbacks callbacks = { 0, &MyDrawColoredPattern, NULL };  
  24.    
  25.     CGContextSaveGState(context);  
  26.     CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern(NULL);  
  27.     CGContextSetFillColorSpace(context, patternSpace);  
  28.     CGColorSpaceRelease(patternSpace);  
  29.    
  30.     CGPatternRef pattern = CGPatternCreate(NULL,  
  31.                                            layer.bounds,  
  32.                                            CGAffineTransformIdentity,  
  33.                                            24,  
  34.                                            24,  
  35.                                            kCGPatternTilingConstantSpacing,  
  36.                                            true,  
  37.                                            &callbacks);  
  38.     CGFloat alpha = 1.0;  
  39.     CGContextSetFillPattern(context, pattern, &alpha);  
  40.     CGPatternRelease(pattern);  
  41.     CGContextFillRect(context, layer.bounds);  
  42.     CGContextRestoreGState(context);   
  43. }  
就是这样,运行代码,你将在图片下面看到一个蓝色的图案

将来

下载源代码点击,

这篇关于CALayer的简单使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1017535

相关文章

Java使用Javassist动态生成HelloWorld类

《Java使用Javassist动态生成HelloWorld类》Javassist是一个非常强大的字节码操作和定义库,它允许开发者在运行时创建新的类或者修改现有的类,本文将简单介绍如何使用Javass... 目录1. Javassist简介2. 环境准备3. 动态生成HelloWorld类3.1 创建CtC

使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解

《使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解》本文详细介绍了如何使用Python通过ncmdump工具批量将.ncm音频转换为.mp3的步骤,包括安装、配置ffmpeg环... 目录1. 前言2. 安装 ncmdump3. 实现 .ncm 转 .mp34. 执行过程5. 执行结

Java使用jar命令配置服务器端口的完整指南

《Java使用jar命令配置服务器端口的完整指南》本文将详细介绍如何使用java-jar命令启动应用,并重点讲解如何配置服务器端口,同时提供一个实用的Web工具来简化这一过程,希望对大家有所帮助... 目录1. Java Jar文件简介1.1 什么是Jar文件1.2 创建可执行Jar文件2. 使用java

C#使用Spire.Doc for .NET实现HTML转Word的高效方案

《C#使用Spire.Docfor.NET实现HTML转Word的高效方案》在Web开发中,HTML内容的生成与处理是高频需求,然而,当用户需要将HTML页面或动态生成的HTML字符串转换为Wor... 目录引言一、html转Word的典型场景与挑战二、用 Spire.Doc 实现 HTML 转 Word1

Java中的抽象类与abstract 关键字使用详解

《Java中的抽象类与abstract关键字使用详解》:本文主要介绍Java中的抽象类与abstract关键字使用详解,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、抽象类的概念二、使用 abstract2.1 修饰类 => 抽象类2.2 修饰方法 => 抽象方法,没有

MyBatis ParameterHandler的具体使用

《MyBatisParameterHandler的具体使用》本文主要介绍了MyBatisParameterHandler的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参... 目录一、概述二、源码1 关键属性2.setParameters3.TypeHandler1.TypeHa

Spring 中的切面与事务结合使用完整示例

《Spring中的切面与事务结合使用完整示例》本文给大家介绍Spring中的切面与事务结合使用完整示例,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考... 目录 一、前置知识:Spring AOP 与 事务的关系 事务本质上就是一个“切面”二、核心组件三、完

使用docker搭建嵌入式Linux开发环境

《使用docker搭建嵌入式Linux开发环境》本文主要介绍了使用docker搭建嵌入式Linux开发环境,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1、前言2、安装docker3、编写容器管理脚本4、创建容器1、前言在日常开发全志、rk等不同

使用Python实现Word文档的自动化对比方案

《使用Python实现Word文档的自动化对比方案》我们经常需要比较两个Word文档的版本差异,无论是合同修订、论文修改还是代码文档更新,人工比对不仅效率低下,还容易遗漏关键改动,下面通过一个实际案例... 目录引言一、使用python-docx库解析文档结构二、使用difflib进行差异比对三、高级对比方

sky-take-out项目中Redis的使用示例详解

《sky-take-out项目中Redis的使用示例详解》SpringCache是Spring的缓存抽象层,通过注解简化缓存管理,支持Redis等提供者,适用于方法结果缓存、更新和删除操作,但无法实现... 目录Spring Cache主要特性核心注解1.@Cacheable2.@CachePut3.@Ca