CALayer 实用属性补充

2018-08-23 11:23:35 浏览数 (1)

为方便对CALayer的学习,特记录以下内容,整理自ios核心动画高级技巧 · GitBook (墙裂推荐阅读此翻译文档)

 contents 属性

这个属性的类型被定义为id(这是由于MacOSX历史原因造成的,因为在Mac中这个属性对CGImage和NSImage都起作用),意味着它可以时任何对象类型,但实际上,如果给contents赋值不是CGImageRef,得到的都将是空白图片。可是CGImageRef属于Core Foundation类型,所以,赋值的时候,需要进行桥接转换。

示例1:  -(void)viewDidLoad { [super viewDidLoad]; UIImage *image = [UIImage imageNamed:@"demoImage"];  self.demoView.layer.contents = (__bridge id )(image.CGImage);  }

contentsGravity

这个属性是NSString类型,它和UIView的contentMode一样,目的是为了处理内容在图层的边界内如何对齐。可选的常量值有以下这些:

kCAGravityCenter

kCAGravityCenter

 kCAGravityTop

kCAGravityTop

 kCAGravityBottom

kCAGravityBottom

 kCAGravityLeft

kCAGravityLeft

 kCAGravityRight

kCAGravityRight

 kCAGravityTopLeft

kCAGravityTopLeft

 kCAGravityTopRight

kCAGravityTopRight

 kCAGravityBottomLeft

kCAGravityBottomLeft

 kCAGravityBottomRight

kCAGravityBottomRight

 kCAGravityResize(默认值)

kCAGravityResize

 kCAGravityResizeAspect

kCAGravityResizeAspect

 kCAGravityResizeAspectFill

kCAGravityResizeAspectFill

 contentsScale

这个属性是浮点类型,默认值为1.0,它定义了像素尺寸和视图大小的比例(类似于分辨率,UIView相似功能的属性是contentScaleFactor)。如果设置了contentsGravity属性为kCAGravityResizeAspect(拉伸)时,将会忽略contentsScale,因为拉伸图片适应图层时,根本不会考虑分辨率问题。当我们使用UIImage时,会获取高质量的图片,但CGImage没有拉伸概念,因此使用CGImage设置图片时,拉伸的因素会在转换的时候丢失,当用代码设置contents图片时,要手动设置图层的contentsScale的属性,避免Retina屏幕显示错误

layer.contentsScale = [UIScreen mainScreen].scale;

contentsScale

maskToBounds

默认情况下,UIView会绘制超过边界的内容或子视图,CALayer也一样。UIView有一个叫做clipsToBounds属性可以用来决定是否显示超出边界的内容,CALaer对应的属性是maskToBounds,设置为YES,会剪去超出边界的部分(不显示)。

 contentsRect

这个属性是CGRect类型,它允许我们设置图层显示内容图片的一个区域。与bounds和frame不同,contentsRect不是使用点来计算的,它使用了单位坐标,值在0~1之间。默认值是{0,0,1,1},意为整个图片大小。

图片选自网络

contentsRect在App中常常用来将拼合的图片裁剪开来,分解成各个部分显示出来。

 示例2:

代码语言:javascript复制
 @interface ViewController()
 @property (strong, nonatomic) IBOutletCollection(UIView) NSArray *spriteImages;
 @end
 @implementation ViewController
 -(void)viewDidLoad {
[super viewDidLoad];
UIImage *image = [UIImage imageNamed:@"compsiteImage"];
NSUInteger count = self.spriteImages.count;
for(int i = 0; i < count; i  ) {
 UIView *view = self.spriteImages[i];
 CGRect rect = CGRectMake(i * 1.0/ count , 0, 1.0/count, 1);
[self addImage:image toView:view withContentsRect:rect];
 }
 }
 -(void)addImage:(UIImage *)image toView:(UIView *)toView withContentsRect:(CGRect)rect{
toView.layer.contents = (__bridge id)image.CGImage;
 toView.layer.contentsRect = rect;
 }

 @end

demo

 contentsCenter

这个属性类型是CGRect,它用来确定图层上可拉伸区域,使用单位坐标,默认值是{0,0,1,1}. 它与UIImage的-resizableImageWithCapInsets:方法相似。

contentsCenter

这个属性是可以在Interface Builder 里面进行配置的。

Stretching

0 人点赞