UIView与CALayer的联系与区别

UIView是iOS系统中界面元素的基础, 所有的界面元素都继承自它, UIView本身完全是由CoreAnimation来实现. 真正的绘图部分, 是由一个CALayer类来管理. UIView更像是一个CALayer的管理器, 所以访问它的与绘图和坐标相关的属性, 如frame, bounds等, 实际上都是在访问其所包含的CALayer的相关属性. 因此, 可以在所有UIView的子类上实现动画效果. UIView继承自UIResponder, 能接收并响应事件, 负责显示内容的管理, 而CALayer继承自NSObject, 不能响应事件, 负责显示内容的绘制.

UIView的layer属性

获取UIView的layer属性:

CALayer *layer = self

UIView的layerClass方法返回layer使用的类. 可以重写该方法, 使UIView的继承类使用指定的CALayer来显示, 如下代码可使其使用OpenGL来进行绘制.

+ (Class)layerClass {return [CAEAGLLayer class];}

对于UIViewController, 可做如下操作让其UIView使用OpenGL来绘制. CALayer的层级结构与UIView的类似, addSublayer与addSubview的作用类似.

CAEAGLLayer *eaglLayer = [CAEAGLLayer layer];eaglLayer;eaglLayer.opaque = YES;eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES],kEAGLDrawablePropertyRetainedBacking,kEAGLColorFormatRGBA8,kEAGLDrawablePropertyColorFormat, nil];[addSublayer:eaglLayer];

当CALayer有了更新, 而不能立即显示, 可使用setNeedsDisplay方法来重绘显示.

[myLayer setNeedsDisplay];// 更新局部区域[myLayer setNeedsDisplayInRect:CGRectMake(100,100,50,50)];// CoreGraphics可以直接使用renderInContext[myLayer renderInContext:UIGraphicsGetCurrent()];CALayer

一个UIView可以有多个CALayer, UIView的尺寸样式都是由内部的CALayer来提供的. 每一个CALayer显示一种效果, 因此, 通过添加多种效果的CALayer, 以增强UIView的显示能力. 如UIView自身不能设置圆角等效果, 而CALayer可设置边框, 圆角, 阴影和变换变形等. 两者都有树状层级结构, CALayer有subLayers, UIView有subViews.

contents属性CALayer *aLayer = [[CALayer alloc] init;aLayer.contents = [[UIImage imageNamed:@”testImage”] CGImage];aLayer.contentsGravity = kCAGravityResizeAspectFill;

这里使用图片给contents赋值的话, 一定要是CGImage. 可以通过设置contentsGravity设置其显示模式, 相当于UIView的contentMode, 如kCAGravityResizeAspectFill 是铺满的 。kCAGravityResizeAspect 是显示自己本身的大小 。 若果图片超出CALayer 可以使用maskToBounds 进行裁剪 ,剪掉超出的部分 (配合圆角使用不错)。

contentsRect

用来裁剪图片, 默认的contentsRect是{0, 0, 1, 1}, 即整个图都默认可见. 如果我们改成{0,0,0.5,0.5} 图像就就会被裁剪掉左上角的1/4.

CALayer效果aLayer.backgroundColor = [[[UIColor redColor] colorWithAlphaComponent:0.2] CGColor];// 边框aLayer.boardColor = [[UIColor blueColor] CGColor];aLayer.boardWidth = 2.0;// 圆角aLayer.cornerRadius = 10.0;// 阴影aLayer.shadowColor = [[UIColor greenColor] CGColor];aLayer.shadowOpacity = 0.5;aLayer.shadowOffset = CGSizeMake(2, 1);[self.view.layer addSublayer:aLayer];

圆角(cornerRadius)和阴影(shadowColor), 二者不能同时出现, 所以可以通过两个重叠的UIView, 分别使其CALayer显示圆角和阴影.

变换

QuartzCore的CATransform3D提供了旋转,缩放和倾斜等变换效果. 添加3D或者仿射变换如下:

myView.layer.transform = CATransform3DMakeScale(-1.0, -1.0, 1.0);CGAffineTransform transform = CGAffineTransformMakeRotation(45.0);myView.layer.affineTransform = transform;

取消动画可以使用[layer removeAllAnimations]; 可参考swift详解之二十四—————CoreAnimation(一)CALayer.

Layer Tree

CALayer内部维护着三份layer tree, 分别是presentLayer Tree(动画树), mode Layer Tree(模型树), Render Tree(渲染树), 在做iOS动画的时候, 我们修改动画的属性, 在动画的其实是Layer的presentLayer的属性值, 而最终展示在界面上其实是提供UIView的modeLayer.

UIView与CALayer的区别

UIView继承自UIResponder,主要特点是可以响应触摸事件。而CALayer是实际的图层内容管理, 不会直接渲染到屏幕上。大家干的的事情不一样,是两个东西,大家的存在互不影响,理所当然。

事件响应

简单将CALayer视作只能显示, 不能响应事件的特殊UIView; 或将UIView视作能接收和响应事件的CALayer. UIKit使用UIResponder作为响应对象, 来响应系统传递过来的事件并进行处理. UIApplication, UIViewController, UIView和所有从UIView派生出来的UIKit类(包括UIWindow)都直接或间接地继承自UIResponder类. UIResponder中定义了处理各种事件和事件传递的接口.处理事件如touchesBegan:withEvent:, touchesMoved:withEvent:, touchesEnded:withEvent:等. 而CALayer直接继承自NSObject, 并没有相应的处理事件的接口. 关于UIResponder的更多内容请参考以下两篇文章: 1. Responder Chain简析 2. 视图和窗口架构

frame, position, bounds调用慢慢学会了长大。流转的时光,

UIView与CALayer的联系与区别

相关文章:

你感兴趣的文章:

标签云: