iOS 开发 UIView和CALayer详解

来源:互联网 发布:官方原版windows xp 编辑:程序博客网 时间:2024/05/18 11:14

UIView

1.UIView是iOS系统中界面元素的基础,所有的界面元素都继承自它。它本身完全是由CoreAnimation来实现的。它真正的绘图部分,是由一个叫CALayer(Core Animation Layer)的类来管理。UIView本身,更像是一个CALayer的管理器,访问它的跟绘图和跟坐标有关的属性,例如frame,bounds等等,实际上内部都是在访问它所包含的CALayer的相关属性。

2.UIView 显示在屏幕上归功于 CALayer,通过调用 drawRect 方法来渲染自身的内容, 调节 CALayer 属性可以调整 UIView 的外观,UIView 继承自 UIResponder,比起 CALayer 可以响应用户事件

CALayer

两者最大的区别是,图层不会直接渲染到屏幕上。
在模型-视图-控制器(model-view-controller)概念里面NSView和UIView是典型的视图部分,但是在核心动画里面图层是模型部分。图层封装了几何、时间、可视化属性,同时它提供了图层现实的内容,但是实际显示的过程则不是由它来完成。
每个可见的图层树由两个相应的树组成:一个是呈现树,一个是渲染树。

  • 4.UIView的layer树形在系统内部,被系统维护着三份copy(这段理解有点吃不准)。

第一份,模型树modeLayer Tree,就是代码里可以操纵的,例如更改layer的属性等等就在这一份。
第二份,动画树presentLayer Tree,这是一个中间层,系统正在这一层上更改属性,进行各种渲染操作。
第三份,渲染树Render Tree,这棵树的内容是当前正被显示在屏幕上的内容。

这三棵树的逻辑结构都是一样的,区别只有各自的属性。

CALayer和UIView的关系

  • CALayer 负责视图中显示内容和动画
  • UIView 负责监听和响应事件
  • 2.View和CALayer的Frame映射及View如何创建CALayer.

  • 一个 Layer 的 frame 是由它的 anchorPoint,position,bounds,和 transform 共同决定的,而一个 View 的 frame 只是简单的返回 Layer的 frame,同样 View 的 center和 bounds 也是返回 Layer 的一些属性。(PS:center有些特列)为了证明这些,我做了如下的测试。

  • UIView主要是对显示内容的管理而 CALayer 主要侧重显示内容的绘制

  • UIView是CALayer的CALayerDelegate, 在代理方法内部[UIView(CALayerDelegate) drawLayer:inContext]调用UIView的drawRect方法, 从而绘制出UIView的内容. UIView的显示内容由内部的CALayer:display方法来实现.

坐标系系统

坐标系系统(对position和anchorPoint的关系还是犯晕)
CALayer的坐标系系统和UIView有点不一样,它多了一个叫anchorPoint的属性,它使用CGPoint结构,但是值域是0~1,也就是按照比例来设置。这个点是各种图形变换的坐标原点,同时会更改layer的position的位置,它的缺省值是{0.5, 0.5},也就是在layer的中央。
某layer.anchorPoint = CGPointMake(0.f, 0.f);
如果这么设置,layer的左上角就会被挪到原来的中间的位置,
加上这样一句就好了
某layer.position = CGPointMake(0.f, 0.f);

为什么CALayer中使用CGColorRef和CGImageRef这2种数据类型,而不用UIColor和UIImage?

  • 首先要知道:CALayer是定义在QuartzCore框架中的;CGImageRef、CGColorRef两种数据类型是定义在CoreGraphics框架中的;UIColor、UIImage是定义在UIKit框架中的

如何选择UIView和CALayer?

CALayer继承自NSObject,而UIView集成自NSResponder.所以UIView是可以相应用户的点击事件的,而CALayer更多的是做渲染和动画效果。
UIView相对于CALayer来说就是多一个事件处理的功能,CALayer是不能处理用户的触摸事件。故如果显示出来的东西需要跟用户进行交互的话,用UIView;如果不需要跟用户进行交互,用UIView或者CALayer都可以。

其实UIView的显示过程

当UIView需要显示时,它内部的层会准备好一个CGContextRef(图形上下文),然后调用delegate(这里就是UIView)的drawLayer:inContext:方法,并且传入已经准备好的CGContextRef对象。而UIView在drawLayer:inContext:方法中又会调用自己的drawRect:方法

在drawRect:中通过UIGraphicsGetCurrentContext()获取的就是由层传入的CGContextRef对象,在drawRect:中完成的所有绘图都会填入层的CGContextRef中,然后被拷贝至屏幕

CALayer 的一些重要属性:

1). shadowPath : 设置 CALayer 背景(shodow)的位置

2). shadowOffset : shadow 在 X 和 Y 轴 上延伸的方向,即 shadow 的大小

3). shadowOpacity : shadow 的透明效果

4). shadowRadius : shadow 的渐变距离,从外围开始,往里渐变 shadowRadius 距离

5). masksToBounds : 很重要的属性,可以用此属性来防止子元素大小溢出父元素,如若防止溢出,请设为 true

6). borderWidth 和 boarderColor : 边框颜色和宽度,很常用

7). bounds : 对于我来说比较难的一个属性,测了半天也没完全了解,只知道可以用来控制 UIView 的大小,但是不能控制 位置

8). opacity : UIView 的透明效果

9). cornerRadius : UIView 的圆角

0 0