(以下内容是我查阅一些资料的整理和自己的理解,如果有不对的地方,欢迎斧正~^_^)
CALayer是什么?
CALayer是UIView中的图层,UIView的内容展示就是通过CALayer来展示的.有人可能会问UIView不是展示内容的吗,怎么会通过CALayer来展示呢?
其实UIView中不止有图层,还有子控件的位置,以及其能接受的响应事件和和事件的处理过程等等一系列的组件组合成的.而每一个UIView都有一个根CALayer来绘制和展示自己的内容.iOS中基本上所有UIView的动画都是通过CALayer来实现的.--在实现核心动画时,本质上是将CALayer中的内容转换成位图(一种图像格式),从而便于图形硬件的操纵.
我们可以用CALayer来做什么?
UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(110, 100, 100, 100)]; [myView setBackgroundColor:[UIColor redColor]]; [self.view addSubview:myView]; [myView.layer setCornerRadius:50];
通过setCornerRadius方法,可以将myView视图的外观设为圆角,setCornerRadius:50 后面这个参数是设置圆角的半径,喜爱面的图片就是实现的效果
在上面的代码下面加上下面两行代码,可以给视图添加边框
[myView.layer setBorderColor:[UIColor whiteColor].CGColor]; [myView.layer setBorderWidth:3.0f];
可以很清楚的看出来,设置边框需要设置边框的颜色和边框的宽度,添加后运行代码效果如下所示
通过CALayer还可以给视图添加阴影,
要设置阴影效果,必须同时指定颜色、透明度、偏移量
在上面代码的基础再加上下面两行代码
[myView.layer setShadowColor:[UIColor blackColor].CGColor]; [myView.layer setShadowOpacity:1.0f]; [myView.layer setShadowOffset:CGSizeMake(10, 10)];
很明显,上面代码第一行是设置阴影颜色,第二行设置阴影透明度,第三行设置阴影的偏离位置,通过调节阴影偏离位置可以调节阴影显示的位置,如果将
CGSizeMake(10, 10) X调为0,将Y调为跟视图尺寸一样高,则会出现倒影效果如下图
但是实际使用的时候貌似有一些控件设置了Layer属性之后不生效,这事为虾米呢?
UIView是视图类的老祖宗,所有视图控件类都继承自UIView类,所以UIView类创建的对象是最纯净的,而像UIImageView和UIButton等这些控件组成比较复杂
所以他们里面的CALayer不止一个
下面来看代码~
UIImage *image = [UIImage imageNamed:@"001"]; UIImageView *imageView = [[UIImageView alloc] initWithImage:image]; [imageView setFrame:CGRectMake(20, 100, 280, 140)]; [self.view addSubview:imageView]; // 设置圆角 [imageView.layer setCornerRadius:50];
写完上面的代码以后,展现在我们面前的应该是一张圆角图片,但是往下看-->
图片还是矩形的,并没有圆角,前面已经说了UIImageView的涂层不止一个,图片应该是没在你设置圆角的那个涂层上,这怎办呢?
虽然UIImageView有很多图层,但UIImageView继承自UIView,既然继承自UIView,他肯定有一个根图层,其他的图层都是根图层的subLayer(子图层)
然后去看一下CALayer的头文件或者google一下~就会发现CALayer有一个
@property BOOL masksToBounds;属性,按一下option看到的帮助里面貌似是说如果这个属性设置为YES,核心动画就会创建一个裁剪过得图层
尝试就一下下面设置maskToBounds的代码
[self.view setBackgroundColor:[UIColor lightGrayColor]]; UIImage *image = [UIImage imageNamed:@"001"]; UIImageView *imageView = [[UIImageView alloc] initWithImage:image]; [imageView setFrame:CGRectMake(20, 100, 280, 140)]; // 在一个UIImageView中,图层不止一个,如果要设置圆角属性,需要设置一个“遮罩”属性 // 此属性的目的是让所有图层跟随父图层一起变化 [imageView.layer setMasksToBounds:YES]; [self.view addSubview:imageView]; // 1. 设置圆角 [imageView.layer setCornerRadius:50];
再运行一下试试~
果真圆角了啊~O(∩_∩)O哈哈~
下面我们来设置一下边框和阴影会不会也出现蛋疼的问题呢?
看下面的代码~
[self.view setBackgroundColor:[UIColor lightGrayColor]]; UIImage *image = [UIImage imageNamed:@"001"]; UIImageView *imageView = [[UIImageView alloc] initWithImage:image]; [imageView setFrame:CGRectMake(20, 100, 280, 140)]; // 在一个UIImageView中,图层不止一个,如果要设置圆角属性,需要设置一个“遮罩”属性 // 此属性的目的是让所有图层跟随父图层一起变化 [imageView.layer setMasksToBounds:YES]; [self.view addSubview:imageView]; // 1. 设置圆角 [imageView.layer setCornerRadius:50]; // 2. 边框 [imageView.layer setBorderWidth:5.0f]; [imageView.layer setBorderColor:[UIColor whiteColor].CGColor]; // 3. 阴影,如果使用阴影,遮罩属性不能设置为YES,具体使用需要取舍 [imageView.layer setShadowOffset:CGSizeMake(10, 10)]; [imageView.layer setShadowOpacity:1.0f]; [imageView.layer setShadowColor:[UIColor blackColor].CGColor];
果然出现蛋疼的问题了,阴影木有粗线
介似为嘛???????google了一下,找到的答案是设置阴影的时不能设置masksToBounds = YES;?果然是熊和鱼掌不能兼得?(鱼和熊掌)
如果不设置masksToBounds会是啥情况?往下看!!!
果然果然~~~~~~见证了奇迹的时刻,阴影是出来了,圆角边框没了,但是边框是按圆角走的...好奇葩?,所以要想圆角+阴影要靠自己了
忘记这个桑心的故事把,下面来看点别的
通过CALayer还可以设置很炫的3D旋转,偏移,缩放效果结合使用效果更好哦
在上面代码的基础上插入以下代码
// 4. 形变属性 // 使用带Make字样的只能单独设置形变,而不带Make的形变是可以叠加的 imageView.layer.transform = CATransform3DScale(imageView.layer.transform, 0.8, 0.8, 1.0); imageView.layer.transform = CATransform3DTranslate(imageView.layer.transform, 0, -100, 0); imageView.layer.transform = CATransform3DRotate(imageView.layer.transform, M_PI_4, 1.0, 1.0, 1.0);
通过单词就可以看出第一行是设置缩放~第二行是设置偏移~第三行是设置旋转~
看看运行效果
成这鸟样了╮(╯▽╰)╭,上面的三行代码可以一行一行试,有助于搞清楚他们都是干啥的
其实也可以通过KVC设置CALayer的属性,来改变图层的外观~(KVC是啥,请自行谷歌~)
删掉刚才加上的4.----代码,然后添加以下代码
// 5. 使用键值路径修改形变属性 // KVC key value coding(键值编码,被称为OC的大招!) // 使用KVC可以让对象之间的耦合度降低,让程序的弹性空间更大,在OC中,有一个id类型,被称为万能指针 // 使用KVC可以间接访问对象内部的属性,前提是必须知道该对象内部属性! [imageView.layer setValue:@(0.5) forKeyPath:@"transform.scale"]; [imageView.layer setValue:@(-100) forKeyPath:@"transform.translation.y"]; [imageView.layer setValue:@(M_PI) forKeyPath:@"transform.rotation"];
看看效果
也形变了(OYE)
但是要用KVC需要知道keyPath才行%>_<%,表紧张,看看下面这张常用的表就行了,需要的时候来取就行了~
keyPath | 说明 |
rotation.x | X轴旋转角度NSNumber |
rotation.y | Y轴旋转角度NSNumber |
rotation.z | Z轴旋转角度NSNumber |
rotation | Z轴旋转角度NSNumber |
scale.x | X轴缩放比例NSNumber |
scale.y | Y轴缩放比例NSNumber |
scale.z | Z轴缩放比例NSNumber |
scale | 三个轴缩放比例NSNumber |
translation.x | X轴平移量NSNumber |
translation.y | Y轴平移量NSNumber |
translation.z | Z轴平移量NSNumber |
translation | X,Y轴平移量的NSValue |