UIView概念是屏幕上的一块矩形块,它可以能够拦截类似于鼠标和触摸手势等用户输入,视图层级关系中可以相互嵌套,一个视图可以管理它的所有子视图的位置.
UILayer概念是和UIView差不多,其实它比UIView更加强大,拥有一些方法和属性来做动画和变换,和UIView最大的不同是CALayer不处理用户交互.
UIView是对CALayer的封装,很多动画效果体现在Layer,两者是平行的层级关系.CALayer是UIView内部实现细节.
一些很牛逼的特效都需要用到它例如:
阴影 圆角 带颜色的边框
3D变换
非矩形范围
透明遮罩
多级非线性动画
在layer中增加子layer
UIView *layerView = [[UIView alloc] initWithFrame:CGRectMake(50, 100, 300, 300)];
[layerView setBackgroundColor:[UIColor whiteColor]];
[self.view addSubview:layerView];
CALayer *blueLayer = [CALayer layer];
blueLayer.frame = CGRectMake(10, 10, 50, 50);
blueLayer.backgroundColor = [UIColor redColor].CGColor;
[layerView.layer addSublayer:blueLayer];
寄宿图(图层中包含的图)
CAlayer中有个属性--contents 这个类型是id 需要填充的是CGImageRef类型,如果直接赋值UIImage会报错,因为CGImageRef是真正的Cocoa对象,而是一个Core Foundation类型.
contentsScale属性定义了寄宿图的像素尺寸和视图大小的比例,默认情况下它是一个值为1.0的浮点型.1.0将会以每个点的1个像素绘制图片,如果设置为2.0,则以每个2个像素绘制图片
UIView *layerView = [[UIView alloc] initWithFrame:CGRectMake(50, 100, 100, 100)];
[layerView setBackgroundColor:[UIColor whiteColor]];
[self.view addSubview:layerView];
layerView.layer.contentsGravity = kCAGravityCenter;
UIImage *image = [UIImage imageNamed:@"test.jpg"];
layerView.layer.contents = (__bridge id)image.CGImage;
layerView.layer.contentsScale = [UIScreen mainScreen].scale;
contentsRect 属性允许我们在图层的边框里显示寄宿图的一个子域,contentsRect不会按照点来计算,它使用了单位坐标,单位坐标指定的0-1之间,是一个相对值,这意味着整个寄宿图默认都是可见的.
图片裁剪
- (void)addSpriteImage:(UIImage *)image withContentRect:(CGRect)rect{
_layerView.layer.contents = (__bridge id) image.CGImage;
_layerView.layer.contentsGravity = kCAGravityResizeAspect;
_layerView.layer.contentsRect = rect;
}
contentsCenter属性其实是一个CGRect 它定义了一个固定的边框和一个图层上的可拉伸的区域.
- (void)addStretchableImage:(UIImage *)image withContentCenter:(CGRect)rect{
_layerView.layer.contents = (__bridge id) image.CGImage;
_layerView.layer.contentsCenter = rect;
}
CALayer有一个可选的delegate属性实现了CALayerDelegate协议,当CALayer需要一个内容特定的信息时会从协议中请求.
CALayer *blueLayer = [CALayer layer];
blueLayer.frame = CGRectMake(50, 50, 100, 100);
blueLayer.backgroundColor = [UIColor blueColor].CGColor;
blueLayer.delegate = self;
blueLayer.contentsScale = [UIScreen mainScreen].scale;
[_layerView.layer addSublayer:blueLayer];
[blueLayer display];
//代理方法
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx{
CGContextSetLineWidth(ctx, 2.0f);
CGContextSetStrokeColorWithColor(ctx, [UIColor redColor].CGColor);
CGContextStrokeEllipseInRect(ctx, layer.bounds);
}
blueLayer 显式调用了display不同于UIView当图层显示在屏幕上CALayer不会自动重绘他的内容,它把决定权交给开发者.