Fork me on GitHub

UIView与CALayer的关系

前言

最近去面试,被面试官问到UIView与CALayer的关系是什么,想了一下支支吾吾地回答了:“UIView负责确定UI的位置,它包含CALAyer,CALayer负责视图内容的绘制位置大小确定等”,鉴于对两者之前的关系的理解的不够透彻,于是有了这篇文章。

首先我们要理解UIView以及它的一个继承关系等

UIView表示屏幕上的一块矩形区域,它是基本上iOS所有可视化控件的父类,UIView可以管理矩形区域里的内容,处理矩形区域的事件,包括对子视图的管理以及动画的实现。

UIKit的控件的继承关系(图片摘自网络):
Alt text)
上面的图是UIKit相关类的继承关系,从上面可以看出,UIView继承自UIResponder,所以UIView可以做事件响应,它也是iOS中所有视图(控件)直接或者间接的父类。

简单介绍一下UIResponder

在UIKit中UIResponder作为响应事件的对象,来响应系统传递过来的事件并进行处理。在UIResponder中定义了处理各种事件传递的接口。
UIApplication、UIViewController、UIView、和所有从UIView派生出来的UIKit类(包括UIWindow)都直接或间接地继承自UIResponder类。
而CALayer直接继承NSObject,并没有相应的处理事件的接口。

UIView和CALayer的关系

在每个UIView实例当中,都有一个默认的支持图层layer,UIView负责创建并且管理这个图层,实际上UIView之所以能够显示,就是因为它里面有这个一个层,才具有显示的功能,UView仅仅是对它的一层封装,实现了CALayer的delegate,提供了处理事件交互的具体功能,还有动画底层方法的高级API,可以说CALayer是UIView的内部实现细节。

如下图(图片来源于网络):
Alt text)

UIView与CALayer的区别

  • UIView能够响应事件,CALayer不可以
  • UIView是CALayer的delegate
  • UIView只是处理事件,CALayer主要负责图层的绘制
  • 每个UIView内部都有一个CALayer在背后提供内容绘制和显示,而且UIView的尺寸样式都由内部的Layer所提供。两者都有树状层级结构,layer内部有SubLayers,View内部有SubViews。但是Layer比View多了AnchorPoint
  • 一个Layer的frame是由它anchorPoint,position,bounds,和 transform 共同决定的,而一个View的frame只是简单的返回Layer的frame
  • 在iOS做动画的时候,修改非RootLayer的属性(譬如位置、背景色等)会默认产生隐式动画,而修改UIView则不会