备注: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
UIView之所以能显示在屏幕上,完全是因为它内部的一个图层,在创建UIView对象时,UIView内部会自动创建一个图层(即CALayer对象),通过UIView的layer属性可以访问这个层
@property(nonatomic,readonly,retain) CALayer *layer;
当UIView需要显示到屏幕上时,会调用drawRect:方法进行绘图,并且会将所有内容绘制在自己的图层上,绘图完毕后,系统会将图层拷贝到屏幕上,于是就完成了UIView的显示
换句话说,UIView本身不具备显示的功能,拥有显示功能的是它内部的图层。
三:使用
通过操作这个CALayer对象,可以很方便地调整UIView的一些界面属性,比如:阴影、圆角大小、边框宽度和颜色等。
1,通过layer设置边框的宽度和颜色
self.layerView.layer.borderColor = [UIColor redColor].CGColor;
注意:这里用CGColorRef
self.layerView.layer.borderWidth = 20;
self.layerView.layer.shadowColor = [UIColor blueColor].CGColor;
self.layerView.layer.shadowOffset = CGSizeMake(10, 10); // 偏移量
self.layerView.layer.shadowOpacity = 0.5; // 不透明度
4.设置内容
self.layerView.layer.contents = (id)[UIImage imageNamed:@"me"].CGImage;
注意:
1,layer中的图片、设置颜色都是CG类型的。
2,image view、view中设置圆角不显示的原因:imageView中的图片不是跟layer,需要将超出的部分切掉,设置它的masktobounds属性,这样阴影也会消失。
5,设置transform属性(UIView的transform是2D效果,lay是3D效果)
self.layerView.layer.transform = CATransform3DMakeRotation(M_PI_4, 1, 1, 1);
kvc设置属性值
NSValue *value = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI_4, 1, 0, 0)];
[self.layerView.layer setValue:value forKeyPath:@"transform"];
对比CALayer,UIView多了一个事件处理的功能。也就是说,CALayer不能处理用户的触摸事件,而UIView可以。
所以,在选择的过程中,需要考虑到实际的情况,如果显示出来的东西需要跟用户进行交互的话,用UIView;如果不需要跟用户进行交互,用UIView或者CALayer都可以
当然,CALayer的性能会高一些,因为它少了事件处理的功能,更加轻量级
每一个UIView内部都默认关联着一个CALayer,我们可用称这个Layer为Root Layer(根层)
所有的非Root Layer,也就是手动创建的CALayer对象,都存在着隐式动画
什么是隐式动画?
当对非Root Layer的部分属性进行修改时,默认会自动产生一些动画效果
而这些属性称为Animatable Properties(可动画属性)
[CATransaction begin];
[CATransaction setDisableActions:YES];
在UIView中绘制图形,获取的上下文就是这个view对应的layer的上下文。在渲染的时候,就是把图形渲染到对应的layer上。
在执行渲染操作的时候,本质上它的内部相当于执行了 [self.layer drawInContext:ctx];
2) 设置CALayer的delegate,然后让delegate实现drawLayer:inContext:方法,当CALayer需要绘图时,会调用delegate的drawLayer:inContext:方法进行绘图。
补充:
1)无论采取哪种方法来自定义层,都必须调用CALayer的setNeedsDisplay方法才能正常绘图。
2)详细现实过程:
当UIView需要显示时,它内部的层会准备好一个CGContextRef(图形上下文),然后调用delegate(这里就是UIView)的drawLayer:inContext:方法,并且传入已经准备好的CGContextRef对象。而UIView在drawLayer:inContext:方法中又会调用自己的drawRect:方法。平时在drawRect:中通过UIGraphicsGetCurrentContext()获取的就是由层传入的CGContextRef对象,在drawRect:中完成的所有绘图都会填入层的CGContextRef中,然后被拷贝至屏幕。
实现drawrect方法就能展示到layer上去