1.简介
-
CALayer
UIView
之所以能显示在屏幕上,完全是因为它内部的一个图层,在创建UIView
对象时,UIView
内部会自动创建一个图层(即CALayer
对象),通过UIView
的layer
属性可以访问这个层
当UIView
需要显示到屏幕上时,会调用drawRect:
方法进行绘图,并且会将所有内容绘制在自己的图层上,绘图完毕后,系统会将图层拷贝到屏幕上,于是就完成了UIView
的显示。因此,通过操作这个CALayer
对象,可以很方便地调整UIView
的一些界面属性,比如:阴影、圆角大小、边框宽度和颜色等。
总结:
UIView
本身不具备显示的功能,拥有显示功能的是它内部的图层。
-
maskToBounds
maskToBound
是CALayer
的属性,设置为YES
时,表示视图的图层上的子图层,如果超出父图层的部分就截取掉,默认为NO
。
2.设置圆角
view.layer.cornerRadius = 10;
如下图:
常见的主要控件只设置
cornerRadius
属性后,发现label
,imageView
,设置image
的button
圆角未设置成功。此时,需加上
layer.maskToBounds = YES;
才能设置成功。
但是,设置
maskToBounds = YES
会触发离屏渲染,过多时,会引起性能问题。黄色的部分表示触发了离屏渲染.png
3.避免离屏渲染
- 根据上述内容,大部分控件不需要设置
masksToBounds = YES
即能达到设置圆角的目的,此时也就不存在离屏渲染的问题。 -
UILabel
设置label的背景颜色时,不使用
label.backgroundColor = [UIColor OrangeColor];
使用
label.layer.backgroundColor = [UIColor orangeColor].CGColor;
label
的backgroundColor
需设置成label
的defaultColor
即clearColor
;且要先于label.layer.backgroundColor
,否则没有圆角效果。
-
UIImage
imageView
与设置了image
的button
其实都属于这个这个问题。要对image
处理。
-
UIImageView
可以直接使用
#import "UIImageView+Category.h"
@implementation UIImageView (Category)
- (void)addCornerRadius:(CGFloat)radius{
UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:radius];
UIGraphicsBeginImageContextWithOptions(self.bounds.size, false, [UIScreen mainScreen].scale);
CGContextAddPath(UIGraphicsGetCurrentContext(), bezierPath.CGPath);
CGContextClip(UIGraphicsGetCurrentContext());
[self.image drawInRect:self.bounds];
UIImage * radiusImg = UIGraphicsGetImageFromCurrentImageContext();
self.image = radiusImg;
UIGraphicsEndImageContext();
}
-
UIButton
等设置image
时使用
#import "UIImage+Category.h"
@implementation UIImage (Category)
-(UIImage*)addCornerRadius:(CGFloat)radius withBounds:(CGRect)rect{
UIGraphicsBeginImageContextWithOptions(rect.size, NO, [UIScreen mainScreen].scale);
[[UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius] addClip];
[self drawInRect:rect];
UIImage * radiusImg = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return radiusImg;
}
对于继承
UIScrollView
的TextView
、UITableView
等子类,默认clipsToBounds = YES
,所以会有离屏渲染。
4.同时设置圆角和阴影
如果设置了maskToBounds
为YES时,shadow
部分也是被截取掉的,不能保证圆角和阴影同时存在。所以用以上方法设置圆角,尤其是UILabel
,UIImageView
,UIButton
等,可以保证其圆角和阴影同时存在。
对于UITableView
,TextView
,UICollectionView
等继承UIScollView
的子类,暂时没有发现好的解决方法,只能给这些view
加一个统一size
的superView
,对其superView
加圆角和阴影。
5.maskToBounds
与clipsToBounds
的区别
1.
maskToBounds
是CALayer
的属性,clipsToBounds
是UIView
新的属性。
2.两者在大多数场景使用效果一样。
3.clipsToBounds
会调用maskToBounds
方法。
网友评论