在iOS中看得见摸得着的东西基本上都是UIView,而UIView之所以能看得见摸得着就是因为他有一个层(CALayer)
@property(nonatomic,readonly,strong) CALayer *layer;
在创建UIView对象时,UIView内部会自动创建一个层(即CALayer对象),通过UIView的layer属性可以访问这个层。当UIView需要显示到屏幕上时,会调用drawRect:方法进行绘图,并且会将所有内容绘制在自己的层上,绘图完毕后,系统会将层拷贝到屏幕上,于是就完成了UIView的显示。
一、CALayer的简单使用
1、直接创建图层显示到屏幕上
CALayer *myLayer = [CALayer layer];
myLayer.bounds = CGRectMake(0, 0, 100, 100);
myLayer.position = CGPointZero;
myLayer.backgroundColor = [UIColor redColor].CGColor;
myLayer.anchorPoint = CGPointMake(0, 0);//锚点的位置
[self.view.layer addSublayer:myLayer];
2、还可以创建显示图片的图层
myLayer.contents = (id)[UIImage imageNamed:@"test"].CGImage;
二、CALayer的属性
以UIView为例:
self.testView.layer.borderWidth = 5.0; //设置边框的宽度
self.testView.layer.borderColor = [UIColor redColor].CGColor; //设置边框的颜色
self.testView.layer.cornerRadius = 10.0; //设置view的圆角
self.testView.layer.shadowColor = [UIColor grayColor].CGColor; //设置阴影的背景色
self.testView.layer.shadowOffset = CGSizeMake(10, 10); //设置阴影 width<0 左,width>0 右, height<0 上, height>0 下
self.testView.layer.shadowOpacity = 1; //设置阴影的不透明度 默认0
//self.testView.layer.masksToBounds = NO; //裁剪超出试图范围的部分 (会把阴影部分裁剪掉)
设置图片的layer属性时有点不同
self.testImageView.layer.borderWidth = 5.0; //设置边框的宽度
self.testImageView.layer.borderColor = [UIColor greenColor].CGColor; //设置边框的颜色
self.testImageView.layer.cornerRadius = 10.0;
/*设置UIImageView的layer属性 和UIView的基本一致。但是在设置图片圆角的时候,必须设置*/
self.testImageView.layer.masksToBounds = YES;
/*因为UIImageView是放在次层上的 而self.testImageView.layer.cornerRadius = 5.0是设置根层上的圆角,所以必须把超出根层的试图裁减掉,次层上的图片才会显示圆角*/
/*****但是设置裁剪圆角后 阴影也会裁减掉****/
self.testImageView.layer.shadowColor = [UIColor grayColor].CGColor; //设置阴影的背景色
self.testImageView.layer.shadowOffset = CGSizeMake(10, 10);
self.testImageView.layer.shadowOpacity = 1; //设置阴影的不透明度 默认0
三、CALayer的position(位置)和anchorPoint(锚点)属性
//position可以用来设置CALayer在父层中的位置,它是以父层的左上角为坐标原点(0, 0)
@property CGPoint position;
//anchorPoint称为"定位点",**它决定着CALayer身上的哪个点会在position属性所指的位置**。它的x、y取值范围都是0~1,默认值为(0.5, 0.5)
@property CGPoint anchorPoint;
下面两句代码设置了myLayer的position为(100, 100),又因为anchorPoint默认是(0.5, 0.5),所以最后的效果是:myLayer的中点会在父层的(100, 100)位置。(看图理解 “它决定着CALayer身上的哪个点会在position属性所指的位置”这句话)
// 设置层的宽度和高度(100x100)
myLayer.bounds = CGRectMake(0, 0, 100, 100);
// 设置层的位置
myLayer.position = CGPointMake(100, 100);
四、CALayer平移、旋转、缩放
1、二位平移、旋转、缩放
//二维缩放 宽1.5倍 高0.5倍 <0反过来
self.testImageView.transform = CGAffineTransformMakeScale(-1.5, 0.5);
//二维旋转 >0顺时针
self.testImageView.transform = CGAffineTransformMakeRotation(-M_PI_4);
//二维平移 tx<0 左,tx>0 右, ty<0 上, ty>0 下
self.testImageView.transform = CGAffineTransformMakeTranslation(50, -50);
2、三维平移、旋转、缩放
//三维旋转 会沿着(0,0,0)->(tx,ty,tz)这条向量轴进行旋转一个角度
testImageView.layer.transform = CATransform3DMakeRotation(M_PI_4, 1, 1, 0);
三维旋转也可以达到二维旋转的效果,即绕着Z轴旋转CATransform3DMakeRotation(M_PI_4, 0, 0, 1)
//三维缩放 tx:长 ty:宽 tz:高 和二维缩放一样<0时反向缩放
testImageView.layer.transform = CATransform3DMakeScale(-1.2, -0.5, 0);
//三维平移 tx:延X轴方向平移>0时向右平移 <0时向左平移 ty、tz和tx类似
testImageView.layer.transform = CATransform3DMakeTranslation(100, 100, 0);
总结:UIView的显示过程(取自MJ视频)
1、当UIView需要显示时,view.layer会准备一个UIGraphicsGetCurrentContext() (图层类型的上下文);
2、调用view.layer.delegate的代理方法 drawLayer:inContext: 并传入刚刚准备好的图层上下文;
3、view的drawLayer:inContext:方法又会调用view的drawRect:方法;
4、view就可以在drawRect:中实现绘图代码,所有东西最终都会绘制到view.layer上;
5、最后系统将view.layer上的图拷贝到屏幕上完成UIView的显示。