【IOS沉思录】UIView和CALayer以及UIWindow的区别与联系

先看UIView和CALayer是什么

苹果官方对这两个类的介绍:UIView CALayer

首先CALayer(层)是一个比UIView更底层的图形类,是对底层图形API(OpenGL ES)一层层封装后得到的一个类,用于展示一些可见的图形元素,保留了一些基本的图形化的操作,但同时由于相对高度的封装,使得操作使用变得很简单。CALayer用于管理图形元素,甚至可以制作动画,他保留了一些几何属性,例如:位置、尺寸、图形变换等等。一般的CALayer是作为UIView背后的支持角色,我们创建了一个UIView也同时存在一个相应的CALayer,UIView作为CALayer的代理角色去实现一些功能,例如常见的,我们为UIView制作一个圆角,就会用到UIView背后的layer操作:

view.layer.cornerRadius = 10

就是说CALayer可以通过UIView很方便的展示操作UI元素,但是CALayer自身单独也可以展示和操作可见元素,且灵活度更高,他自身有一些可见可设置的属性,例如:背景色,border边框,阴影等等。

另外UIView简单说是一个可以在里面渲染可见内容的矩形框,并且重要的是它里面的内容可以和用户进行交互,UIView可以对交互事件进行处理。除了其背后CALayer的图形操作支持,UIView自身也有像设置背景色等最基本的属性设置。

UIView和CALayer的联系

UIView和CALayer的主要联系上面已经提到,CALayer在UIView背后提供更加丰富灵活的图形操作,UIView作为CALayer的代理更加快速的帮CALayer显示一些常用的UI元素并提供交互。

UIView和CALayer的区别
  • 首先CALayer是比UIView更底层的低级类。UIView是UIKit框架中的高级类,属于顶层可交互高级类。而CALayer来自于QuartzCore.framework,是一个承载底层绘制内容的对象。
  • UIView和CALayer的最明显区别在于他们的可交互性,即UIView可以响应用户事件,而CALayer则不可以,原因可以从这两个类的继承关系上看出,UIView是继承自UIRespinder的,明显是专门用来处理响应事件的,而CALayer是直接继承自NSObject无法进行交互。
    这里写图片描述
最后说一下UIWindow

UIWindow

从上面图中的继承关系会发现UIWindow居然是UIView的子类,因为UIWindow在应用中是作为根视图来承载UIView元素的,也就是说根父视图却是子视图的子类,有点违背直觉。

但事实就是这样,UIWindow提供一个区域(一般就是整个屏幕)来显示UIView,并且将事件分发给UIView。一个应用一般只有一个UIWindow,但特殊情况也会创建子UIWindow,例如实现一个始终漂浮在顶层的悬浮窗,就可以使用一个UIWindow来实现。

关于如何使用UIWindow创建悬浮窗:http://blog.csdn.net/cordova/article/details/51675431

什么是层对象?除了CALayer系统还提供了那些常用的有绘制功能的layer类?

Layer层对象是用来展示可见内容的一种数据对象,常在视图中用来渲染视图内容。一般的层对象在界面中可以实现一些复杂的动画或者其他类型的一些复杂特效。

常见的几个其他自身具有绘制功能的专用layer还有:CATextLayer、CAShapeLayer、CAGradientLayer,这里给出使用示例。其他还有用于3D图形变换的CATransformLayer、实现滚动视图的CAScrollLayer、专门播放视频的AVPlayerLayer和制作粒子特效的CAEmitterLayer等等。他们都是继承自CALayer的,和CALayer一样都来自QuartzCore.framework框架。

CATextLayer:这个类是用来实现更加灵活的文字布局和渲染的,它几乎包含了UILabel的所有特性并在此基础上增加了很多更强大的功能,包括字体、尺寸、前景色和下划线等文字效果,同时CATextLayer的渲染效率明显高于UILabel。

通过CALayer来实现一个UIlabel的示例如下:

- (void)viewDidLoad {
    [super viewDidLoad];
    /* 创建一个字符承载视图 */
    UIView *textView = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 200, 50)];

    CATextLayer *text = [CATextLayer layer];
    text.frame = textView.frame;
    text.string = @"CAText";
    /* 文字前景色和背景色 */
    text.foregroundColor = [UIColor whiteColor].CGColor;
    text.backgroundColor = [UIColor blackColor].CGColor;
    /* 文字超出视图边界裁剪 */
    text.wrapped = YES;
    /* 文字字体 */
    text.font = (__bridge CFTypeRef)[UIFont systemFontOfSize:30].fontName;
    /* 文字居中 */
    text.alignmentMode = kCAAlignmentCenter;
    /* 适应屏幕retina分辨率,不然会像素化变模糊 */
    text.contentsScale = [[UIScreen mainScreen] scale];

    [textView.layer addSublayer:text];
    [self.view addSubview:textView];
    }

这里写图片描述

CAShapeLayer:用来专门绘制矢量图形的图形子类,例如可以指定线宽和颜色等利用CGPath绘制图形路径,可以实现图形的3D变换效果,渲染效率比Core Graphics快很多,而且可以在超出视图边界之外绘制,即不会被边界裁减掉。

这里展示使用CAShapeLayer绘制一个圆形的实例:

- (void)viewDidLoad {
    [super viewDidLoad];

    /* 创建圆形路径 */
    UIBezierPath *path = [[UIBezierPath alloc] init];
    /* 起点要在圆心水平右侧半径长度处 */
    [path moveToPoint:CGPointMake(200, 100)];
    /* 添加圆形弧路径 */
    [path addArcWithCenter:CGPointMake(150, 100) radius:50 startAngle:0 endAngle:2*M_PI clockwise:YES];

    /* 创建图形层 */
    CAShapeLayer *layer = [CAShapeLayer layer];
    /* 路径线的颜色 */
    layer.strokeColor = [UIColor redColor].CGColor;
    /* 闭合图形填充色,这里设置透明 */
    layer.fillColor = [UIColor clearColor].CGColor;
    /* 线宽 */
    layer.lineWidth = 10;
    /* 线的样式:端点、交点 */
    layer.lineCap = kCALineCapRound;
    layer.lineJoin = kCALineJoinRound;
    /* 设置图形路径 */
    layer.path = path.CGPath;

    [self.view.layer addSublayer:layer];
    }
@end

这里写图片描述

CAGradientLayer:也是一个硬件加速的高性能绘制图层,主要用来实现多种颜色的平滑渐变效果。这里给出一个三种颜色从正方形左上角到右下角的渐变效果示例:

- (void)viewDidLoad {
    [super viewDidLoad];
    /* 创建layer承载视图 */
    UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 150, 150)];

    CAGradientLayer *layer = [CAGradientLayer layer];
    layer.frame = containerView.bounds;
    /* 依次设置渐变颜色数组 */
    layer.colors = @[(__bridge id)[UIColor greenColor].CGColor,(__bridge id)[UIColor yellowColor].CGColor,(__bridge id)[UIColor orangeColor].CGColor];
    /* 颜色从起点到终点按比例分段位置 */
    layer.locations = @[@0.0, @0.3, @0.5];
    /* 颜色渐变的起点和终点:(0,0)~(1,1)表示左上角到右下角 */
    layer.startPoint = CGPointMake(0, 0);
    layer.endPoint = CGPointMake(1, 1);

    [containerView.layer addSublayer:layer];
    [self.view addSubview:containerView];
}

这里写图片描述


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr_厚厚

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值