IOS开发-CALayer和UIView详细汇总

1.    CALayer和UIView之间的关系:

  • 在iOS系统中,你能看得见摸得着的东西基本上都是UIView,比如UI控件、图标等等,都是UIView。
  • 其实UIView之所以能显示在屏幕上,完全是因为它内部的一个层(CALayer)。
  • 在创建UIView对象时,UIView内部会自动创建一个层(即CALayer对象),通过UIView的layer属性可以访问这个层。当UIView需要显示到屏幕上时,会调用drawRect:方法进行绘图,并且会将所有内容绘制在自己的层上,绘图完毕后,系统会将层拷贝到屏幕上,于是就完成了UIView的显示。
  • 换句话说,UIView本身不具备显示的功能,是它内部的层才有显示功能。
  • UIView之所以能够显示,完全是因为内部的CALayer对象。因此,通过操作这个CALayer对象,可以很方便地调整UIView的一些界面属性,比如:阴影、圆角大小、边框宽度和颜色等。

设置图片的圆角和旋转:

1 UIImageView *im = [[UIImageView alloc]init];
2     im.frame = CGRectMake(100, 100, 100, 100);
3     im.image = [UIImage imageNamed:@"收藏背景"];
4     im.layer.cornerRadius = 10;
5     im.layer.masksToBounds = YES;
6     im.layer.transform = CATransform3DMakeRotation(M_PI_4, 0, 0, 1);
7     [self.view addSubview:im];

2.UIView可以通过addSubview:方法添加子视图,类似地,CALayer可以通过addSublayer:方法添加子层

 1   CALayer *myLayer = [CALayer layer];
 2  // 设置层的宽度和高度(100x100)
 3  myLayer.bounds = CGRectMake(0, 0, 100, 100);
 4   // 设置层的位置
 5   myLayer.position = CGPointMake(200, 100);
 6   // 设置需要显示的图片
 7   myLayer.contents = (id)[UIImage imageNamed:@"0000.png"].CGImage;
 8   // 设置层的圆角半径为10
 9   myLayer.cornerRadius = 10;
10  // 如果设置了图片,需要设置这个属性为YES才有圆角效果
11   myLayer.masksToBounds = YES;
12
13  // 添加myLayer到控制器的view的layer中
14  [self.view.layer addSublayer:myLayer];
补充:CGImage是一种CGImageRef类型的数据比如处理图片只显示某部分的时候,就用到了CGImageRef
 1    UIImage *ima = [UIImage imageNamed:@"收藏背景"];
 2 //   图片中需要显示的部分
 3     CGRect rect = CGRectMake(50, 50, 70, 70);
 4 //    获得显示部分的数据
 5     CGImageRef imageref = CGImageCreateWithImageInRect([ima CGImage], rect);
 6 //    将数据转化为图片
 7     UIImage *subimage = [UIImage imageWithCGImage:imageref];
 8     UIImageView *imageview = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
 9     imageview.image = subimage;
10     [self.view addSubview:imageview];

3.为什么CALayer中使用CGColorRef和CGImageRef这2种数据类型,而不用UIColor和UIImage?

* 首先要知道:CALayer是定义在QuartzCore框架中的;CGImageRef、CGColorRef两种数据类型是定义在CoreGraphics框架中的;UIColor、UIImage是定义在UIKit框架中的

* 其次,QuartzCore框架和CoreGraphics框架是可以跨平台使用的,在iOS和Mac OS X上都能使用,但是UIKit只能在iOS中使用

* 因此,为了保证可移植性,QuartzCore不能使用UIImage、UIColor,只能使用CGImageRef、CGColorRef

* 不过很多情况下,可以通过UIKit对象的特定方法,得到CoreGraphics对象,比如UIImage的CGImage方法可以返回一个CGImageRef

4.如何选择UIView和CALayer?

UIView相对于CALayer来说就是多一个事件处理的功能,CALayer是不能处理用户的触摸事件。故如果显示出来的东西需要跟用户进行交互的话,用UIView;如果不需要跟用户进行交互,用UIView或者CALayer都可以。

5.其实UIView的显示过程

当UIView需要显示时,它内部的层会准备好一个CGContextRef(图形上下文),然后调用delegate(这里就是UIView)的drawLayer:inContext:方法,并且传入已经准备好的CGContextRef对象。而UIView在drawLayer:inContext:方法中又会调用自己的drawRect:方法

在drawRect:中通过UIGraphicsGetCurrentContext()获取的就是由层传入的CGContextRef对象,在drawRect:中完成的所有绘图都会填入层的CGContextRef中,然后被拷贝至屏幕

6.自定义层

a.新建一个继承于CALayer的类AACALayer,然后覆盖drawInContext:方法,在里面绘图

 1 -(void)drawInContext:(CGContextRef)ctx{
 3     CGContextSetRGBFillColor(ctx, 0, 1, 0.5, 1);//填充,出现实心
 5 //    起点
 7     CGContextMoveToPoint(ctx, 50, 0);
 9 // 从(50, 0)连线到(0, 100)
11     CGContextAddLines(ctx, 0, 100);
13 // 从(0, 100)连线到(100, 100)
15     CGContextAddLineToPoint(ctx, 100, 100);
17 //    绘制路径
19     CGContextClosePath(ctx);
20
21  }

则每次创建AACALayer,都会绘制一个三角形

1 AALayer *layer = [AALayer layer];
2  // 设置层的宽高
3  layer.bounds = CGRectMake(0, 0, 100, 100);
4  // 设置层的位置
5  layer.position = CGPointMake(100, 100);
6  // 开始绘制图层
7  [layer setNeedsDisplay];//写这个方法才会自动触发 drawInContext:的方法
8 [self.view.layer addSublayer:layer];

b.不想写子类,也可以直接使用代理可以新建层,drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx中绘图,但是不能将UIView设置为它的代理,否则和UIView内部就冲突了,因为UIView已经是内部根图层的degegate了。

 1  CALayer *layerr = [CALayer layer];
 2   // 设置层的宽高
 3   layerr.bounds = CGRectMake(0, 0, 100, 100);
 4   // 设置层的位置
 5   layerr.position = CGPointMake(100, 100);
 6  laere.delegate - self;
 7   // 开始绘制图层
 8   [layer setNeedsDisplay];//无论采取哪种方法来自定义层,都必须调用CALayer的setNeedsDisplay方法才能正常绘图。
 9  [self.view.layer addSublayer:layer];
10
11 //在代理方法中
12 - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
13      // 设置颜色
14      CGContextSetRGBStrokeColor(ctx, 0, 0, 1, 1);//这不填充,空心
15      // 设置边框宽度
16      CGContextSetLineWidth(ctx, 5);
17
18      // 将矩形放到路径中
19      CGContextAddRect(ctx, layer.bounds);
20
21      // 绘制路径
22      CGContextStrokePath(ctx);
23  } 
时间: 2024-10-23 17:14:28

IOS开发-CALayer和UIView详细汇总的相关文章

100个iOS开发/设计程序员面试题汇总,你将如何作答?

100个iOS开发/设计程序员面试题汇总,你将如何作答? 雪姬 2015-01-25 19:10:49 工作职场 评论(0)   无论是对于公司还是开发者或设计师个人而言,面试都是一项耗时耗钱的项目,本文作者Cameron Banga从编程.设计.App Store等各个方面对iOS开发者及设计师在面试时可能会遇到的问题进行了筛选与汇总.一方面,能够帮助HR在短时间内获取更多反馈信息,更好地甄选合适人选,而iOS开发者及设计师在寻找相关工作时,也可作为参考,为面试做好万全准备. 常见问题 你昨天

iOS开发之指定UIView的某几个角为圆角

本文转载至 http://sjh787291806.blog.163.com/blog/static/21396319620131015105856616/ 如果需要将UIView的4个角全部都为圆角,做法相当简单,只需设置其Layer的cornerRadius属性即可(项目需要使用QuartzCore框架).而若要指定某几个角(小于4)为圆角而别的不变时,这种方法就不好用了. 对于这种情况,Stackoverflow上提供了几种解决方案.其中最简单优雅的方案,就是使用UIBezierPath.

iOS开发~CocoaPods使用详细说明

一.概要 iOS开发时,项目中会引用许多第三方库,CocoaPods(https://github.com/CocoaPods/CocoaPods)可以用来方便的统一管理这些第三方库(从一个坑出来,又进了另一个坑而已--). 二.安装 由于网上的教程基本都大同小异,但细节之处还不是很完善,所以借机会在这里补充下: 注:要使用CocoaPods,那就要下载安装它,而下载安装CocoaPods需要Ruby环境 1.Ruby环境搭建 当前安装环境为Mac mini 10.8.5.Mac  OS本身自带

ios开发工程师常见面试题汇总

经过本人最近的面试和对面试资料的一些汇总,准备记录这些面试题,以便ios开发工程师找工作复习之用,本人希望有面试经验的同学能和我同时完成这个模块,先出面试题,然后会放出答案. 1.Object-c的类可以多重继承么?可以实现多个接口么?Category是什么?重写一个类的方式用继承好还是分类好?为什么? 2.#import 跟#include 又什么区别,@class呢: #import<> 跟 #import""又什么区别? 3.属性readwrite,readonly,

iOS开发~CocoaPods使用详细说明【转】

一.概要 iOS开发时,项目中会引用许多第三方库,CocoaPods(https://github.com/CocoaPods/CocoaPods)可以用来方便的统一管理这些第三方库. 二.安装 由于网上的教程基本都大同小异,但细节之处还不是很完善,所以借机会在这里补充下: 注:要使用CocoaPods,那就要下载安装它,而下载安装CocoaPods需要Ruby环境 1.Ruby环境搭建 当前安装环境为Mac mini 10.8.5.Mac  OS本身自带Ruby,但还是更新一下保险,因为我第一

iOS开发 - CALayer图层

CALayer的基本使用 在iOS中,你能看得见摸得着的东西基本上都是UIView,比如一个按钮.一个文本标签.一个文本输入框.一个图标等等,这些都是UIView 其实UIView之所以能显示在屏幕上,完全是因为它内部的一个图层 在创建UIView对象时,UIView内部会自动创建一个图层(即CALayer对象),通过UIView的layer属性可以访问这个层 @property(nonatomic,readonly,retain) CALayer *layer; 当UIView需要显示到屏幕上

iOS开发之指定UIView的某几个角(小于4)为圆角

在iOS开发中,我们经常会遇到View设置圆角的问题,如果需要将UIView的4个角全部都为圆角,做法相当简单,只需设置其Layer的cornerRadius属性即可(项目需要使用QuartzCore框架).而若要指定某几个角(小于4)为圆角而别的不变时,这种方法就不好用了.如图: 对于后者这种情况,下面给出一种比较简单优雅的方案,就是使用UIBezierPath. 示例代码如下: UIView *testView = [[UIView alloc] initWithFrame:CGRectMa

【iOS开发-14】UIView的属性,父视图和子视图的层级操作,子视图的自适应模式,外加一个定时器

(1)UIView视图frame的设置,四个参数,前2个确定位置,后2个确定大小. (2)UIView的内容模式contentMode,和在UIImage中说的是一样的,而且在UIImage中展示更容易理解. (3)UIView最重要的就是父视图和子视图之间的关系,以及父视图操作子视图(增加一个子视图,把一个子视图放到最下面最上面.交换两个子视图的加载顺序等等) (4)还有一个重要的是,父视图如果发生变化,子视图怎么自动调整布局:先让父视图允许子视图干这个事,即把父视图的属性autoresize

iOS开发中 Quartz2D使用详细 简介

1> Quartz2D简介 *  PPT简介 什么是Quartz2D?二维的绘图引擎 什么是二维?平面 什么是引擎?经包装的函数库,方便开发者使用.也就是说苹果帮我们封装了一套绘图的函数库 同时支持iOS和Mac系统什么意思?用Quartz2D写的同一份代码,既可以运行在iphone上又可以运行在mac上,可以跨平台开发. 开发中比较常用的是截屏/裁剪/自定义UI控件. Quartz2D在iOS开发中的价值就是自定义UI控件. 图形上下文的数据类型和作用. 有多少种上下文. 自定义控件的步骤.