核心动画渲染架构(Core Animation Rendering Architecture)

转载:http://www.devdiv.com/forum.php?mod=viewthread&tid=123582

显而易见,core animation层和cocoa试图有很多相似之处,但是,最大的概念上的不同是,core animation层从不直接渲染到屏幕。

显然,NSView和UIView在MVC设计模式中属于视图对象,不过Core animation层实际上是模型对象。虽然core animation层封装了几何,定时以及视觉属性,也提供被显示的内容,但实际的显示并非是层的责任。

每个可见的层树(layer tree)由两组相应的树所支持:展示树(presentation tree)和渲染树(render tree)。图1显示了MAC OS X上层树使用core animation层类的一个例子。

图 1  核心动画渲染架构


层树包含了每个层对象的值,也就是你在为层属性赋值时设定的那些值。

展示树包含了当动画进行时正展示给用户的值,比如,为层设置一个新的backgroundColor值立即改变了层树的值,但是,展示树在显示给用户时,其中对应层的backgroundColor值将使用内插颜色值(interpolated colors)更新。

在渲染层时,渲染树使用了展示树中的值。渲染树负责执行独立于应用程序活动的混合操作;为了将对应用程序运行循环(run loop)的影响降至最低,渲染由单独的进程或线程完成。

在一个动画事务执行中,你可以查询它相应的展示层的一个CALayer实例。如果你打算改变当前动画并想用当前的显示状态开始一个新动画,这会相当有用。


原文地址:https://developer.apple.com/libr ... /uid/TP40006655-SW1

参考:http://www.cocoachina.com/bbs/read.php?tid=84461


层的几何特征和变换

原文:https://developer.apple.com/libr ... rticles/Layers.html


这一章讲述了层的几何组件,这些组件之间的联系,以及变幻矩阵如何产生复杂的变幻效果。

层坐标系

层的坐标系因平台而异。iOS中,默认的坐标系原点在层的左上角,往原点右下方取正值。在MAC OS X中,默认坐标系原点在左下角,往原点右上方向取正值。所有的坐标值规定为浮点数。在指定平台上创建的层使用该平台的默认坐标系。

每个层对象定义和维护着自身的坐标系,层的所有内容相对于此坐标系定位。这对于层内容和子层来说都适用。因为每个层定义了自己的坐标系,CALayer类提供了在不同层的坐标系之间转换点,矩形和尺寸值的方法。

一些层-相关的属性用单位坐标空间来估算他们的值。单位坐标空间是一种方法,用来指定和层的边界有关的值,但不和确切的边界值相关。在单位坐标空间里,一个给定的x或者y坐标的范围总在0.0到1.0之间。在x轴向指定0.0在层的左边缘产生点,指定1.0则在右边缘产生点。(对于y值来说,哪个值表示上边缘或下边缘和具体的平台有关。)一个(0.5,0.5)的点在层的正中产生一个点。

指定层的几何特性
虽然在许多方面,层和层树类似于视图和视图层级,层的几何特性是不同的,并且通常更简单。层的所有几何属性,包括变换矩阵,都可以或隐式或显式的产生动画。

图1 CALayer的几何属性


position属性是一个CGPoint,它指定了层相对于父层的位置,并用父层坐标系表示。
bounds属性是一个CGRect,它提供了层的尺寸(bounds.size)和原点(bounds.origin)。在你覆盖层的绘图方法时,边界(bounds)的原点用于图形环境(graphics context)的原点。

层有一个隐式的frame,它是一个综合position,bounds,anchorPoint和transform属性的函数。设置新的frame矩形会适当的修改position和bounds属性,但是frame自身不被保存。当新的frame矩形被设置时,边界原点(bounds origin)不受影响,而边界尺寸(bounds size)被设为frame的尺寸。层的position被设置到相对于锚点(anchor point)的恰当位置。当你获取frame属性值时,它会根据position,bounds和anchorPoint属性进行计算。

anchorPoint属性是一个CGPoint,它指定了层边界以内相对position坐标的一个位置。锚点指定了bounds如何相对于position属性定位,同时为变换提供中心点。它以单位坐标系统表示,取值(0.0, 0.0)时最接近层的原点,取值(1.0, 1.0)时位于原点的对角。对层的父层(如果有的话)进行变换可以改变anchorPoint的方向,这个方向依赖于父层坐标系的y轴向。

指定层的frame时,position会相对于锚点进行设置。而当指定层的position时,bounds会相对于锚点进行设置。

iOS注意事项:下面的例子显式了Mac OS X的一个层,默认坐标系统的原点位于左下角。在iOS上,层的原点位于左上角,往右下方向取正值。这对显式的数据有影响,但概念相同。

图2 显式了锚点的三个示例值。

图2 三个anchorPoint值


anchorPoint的默认值为(0.5, 0.5),对应层边界的中心(图中A点),B点显式了设置为(0.0, 0.5)的锚点,C点(1.0, 0.0)导致层的position设置到frame的右下角。本图限于表示MAC OS X上的层,在iOS上,层使用不同的坐标系,(0.0, 0.0)表示左上角,(1.0, 1.0)表示右下角。

frame,bounds,position和anchorPoint属性之间的关系如图3所示。

图3 层原点在(0.5, 0.5)


本例中,anchorPoint取默认值(0.5, 0.5),对应于层边界的中心。层的position被设为(100.0, 100.0),bounds设为矩形(0.0, 0.0,120.0,80.0)。结果是frame属性计算结果为(40.0,60.0,120.0,80.0)。
如果你创建新层,并将frame属性设置为(40.0,60.0,120.0,80.0)的话,position属性将被自动设置到(100.0,100.0),bounds属性也自动被设为(0.0,0.0,120.0,80.0)。

图4显式了一个层,它和图3中的层具有相同frame属性。但是,这次anchorPoint被设置为(0.0, 0.0),对应于层的左下角。


因为frame属性被设为(40.0, 60.0, 120.0, 80.0),bounds属性值同上,但position的值发生了改变。

和cocoa视图相比,层的几何特性的另一处不同点是,你可以为层的四角设置圆角半径,cornerRadius属性指定了一个半径,层用它来绘制内容,剪切子层,以及绘制边框和阴影。

zPosition属性指定了层位置的z轴成分。zPosition意图用于设置层相对于其兄弟层的可见位置。它不可以被用来在同一级层间进行排序,而排序应该在子层数组(sublayer array)中进行。


变换层的几何特性

层被创建后,就可以用矩阵变换对层的几何特性进行变换了。CATransform3D数据结构定义了一个同质的三维变换(一个4x4的CGFloat矩阵),它被用来对图层进行旋转,缩放,位移,倾斜以及应用透视变换。

层有两个属性用于指定变换矩阵:transform和sublayerTransform。transform属性指定的矩阵是相对于层的anchorPoint并应用到层和其子层上的。图3演示了使用(0.5, 0.5)的anchorPoint时旋转和缩放如何影响一个层。图4演示了使用(0.0, 0.0)的anchorPoint时旋转和缩放如何影响一个层。sublayerTransform指定的矩阵应用到层的子层上,而不应用于层自身。

你可以用以下几种方式创建和修改CATransform3D数据结构:
1.使用CATransform3D函数
2.直接编辑数据结构成员
3.使用键值编码(Key-Value Coding)和键路径

CATransform3DIdentity常量是单位矩阵,即没有应用缩放,旋转,倾斜或透视的矩阵。对层应用单位矩阵导致它显式默认的几何特性。

变换函数
核心动画中的变换函数用来操作矩阵。你可以用这些函数(表1中列出的)构造出一个矩阵,然后相应的修改transform或sublayerTransform属性,应用到层或其子层。变换函数可以作用于或者返回一个CATransfrom3D数据结构。这让你能够构造出简单或复杂的变换,并且你随时可以复用它们。


表1 CATransform3D变换函数,用于移动,旋转和缩放

函数及用途

CATransform3DMakeTranslation
返回移动'(tx, ty, tx)'的变换。 t' = [1 0 0 0; 0 1 0 0; 0 0 1 0; tx ty tz 1].

CATransform3DTranslate
将't' 平移 '(tx, ty, tz)' 并返回结果: * t' = translate(tx, ty, tz) * t.

CATransform3DMakeScale
返回缩放'(sx, sy, sx)'的变换。: * t' = [sx 0 0 0; 0 sy 0 0; 0 0 sz 0; 0 0 0 1].

CATransform3DScale
将 't' 缩放 '(sx, sy, sz)' 并返回结果: * t' = scale(sx, sy, sz) * t.

CATransform3DMakeRotation
返回以向量'(x,y,z)'弧度的'角'旋转的变换。如果向量长度为0返回单位矩阵。

CATransform3DRotate
将't' 以向量'(x,y,z)'弧度的'角'旋转并返回结果. t' = rotation(angle, x, y, z) * t.


旋转的角度以弧度而不是角度为单位。下面的函数允许你在弧度和角度之间转换。

CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;};

CGFloat RadiansToDegrees(CGFloat radians) {return radians * 180 / M_PI;};


core animation提供了一个反转矩阵的变换函数,CATransform3DInvert。反转一般用于对被变换对象中的点提供反向变换。反转用于需要从已经进行矩阵变换后恢复一个值:反转这个矩阵,乘上这个反转矩阵的值,结果得到了原来的值。

也有些函数用来将CATransfrom矩阵转换为CGAffineTransfrom矩阵,如果CATransfrom矩阵可以那样表示的话。


表2 CATransfrom变换函数,用于CGAffineTransfrom转换

函数及用途

CATransform3DMakeAffineTransform
返回一个同传入的仿射矩阵效果相同的CATransfrom3D

CATransform3DIsAffine
如果CATransfrom3D可以确切的代表一个仿射矩阵的话,返回YES.

CATransform3DGetAffineTransform
返回传入的CATransform3D代表的仿射矩阵。

还有些函数提供比较变换矩阵是否和单位矩阵或另一个矩阵相同的功能。


表3 CATransform3D变换函数,用于检测相等性

函数及用途

CATransform3DIsIdentity
如果变换是单位变换,返回YES。

CATransform3DEqualToTransform
如果两个变换完全相等,返回YES。


编辑变换的数据结构(Modifying the Transform Data Structure)

你可以编辑CATransform3D数据结构的任何成员的值,列表1包含了CATransform3D结构的定义,结构成员位于相应的矩阵位置上。

列表1 CATransform3D结构

struct CATransform3D
 
{
 
  CGFloat m11, m12, m13, m14;
 
  CGFloat m21, m22, m23, m24;
 
  CGFloat m31, m32, m33, m34;
 
  CGFloat m41, m42, m43, m44;
 
};
 
  
 
typedef struct CATransform3D CATransform3D;



列表2 中阐明了如何将一个CATransform3D配置为透视变换。

列表2 直接编辑CATransform3D数据结构

CATransform3D aTransform = CATransform3DIdentity;
 
// zDistance的值影响变换的锐利度
zDistance = 850;
 
aTransform.m34 = 1.0 / -zDistance;




使用键路径编辑变换(Modifying a Transform Using Key Paths)

core animation扩展了键值编码协议,以允许利用键路径读写层的CATransform3D矩阵的常用值。表4描述了transfrom和sublayerTransform的键路径,它们遵守KVC和KVO协议。

表4 CATransform3D键路径

键路径
描述

rotation.x
x轴向旋转,以弧度计。

rotation.y
y轴向旋转,以弧度计。

rotation.z
z轴向旋转,以弧度计。

rotation
x轴向旋转,以弧度计。和rotation.z一样。

scale.x
x轴向缩放因子。

scale.y
y轴向缩放因子。

scale.z
z轴向缩放因子。

scale
三个方向缩放因子的平均值。

translation.x
x轴向位移。

translation.y
y轴向位移。

translation.z
z轴向位移。

translation
x和y轴向位移。 值为一个 NSSize 或者 CGSize。


你不能对objective-c 2.0属性指定一个结构键路径。这不管用:
myLayer.transform.rotation.x=0;

而是应该使用setValue:forKeyPath或者valueForKeyPath:,如下:
[myLayer setValue:[NSNumber numberWithInt:0] forKeyPath:@"transform.rotation.x"];

提供层内容(Providing Layer Content)

原文地址: https://developer.apple.com/libr ... /uid/TP40006642-SW1

当你使用cocoa视图时,要想显示点东西,你不得不写个NSView或者UIView的子类,然后实现drawRect:。但是CALayer实例经常可以直接用,不需要子类化。因为CALayer是遵守了键值编码的容器类,也就是说,你能在任何实例中保存任意的值,子类化经常可以被完全无视。

提供CALayer内容

用下面任意一种方式可以指定CALayer的内容:
1.用一个CGImageRef显式的设置层实例的contents属性,一个CGImageRef包含了内容图片。
2.指定一个委托,让委托提供或者绘制内容。
3.子类化CALayer,覆盖它的显式方法之一。

设置内容属性
一个层内容图片,是由contents属性指定的一个CGImageRef。它可以由其他对象在层创建时完成(就像表3中那样),或者在任何别的时间完成。

列表1  设置层的内容属性
view source
print ?
CALayer *theLayer;
 
// 创建层,设置层的bounds和position
theLayer=[CALayer layer];
theLayer.position=CGPointMake(50.0f,50.0f);
theLayer.bounds=CGRectMake(0.0f,0.0f,100.0f,100.0f);
 
// 用theImage指定的CGImageRef设置content属性(在别的地方加载的)
theLayer.contents=theImage;
用委托提供内容
你可以为你的层画上内容,或者你可以选择,创建一个委托类,这个类实现了displayLayer:或者drawLayer:inContext:方法之一,这样能将设置层内容的行为更好的封装起来。

实现了委托方法来画内容,并不意味着让层能自动的用这个实现来画画。而是,你必须显式的告诉层实例,重新缓存内容,你可以向它发setNeedDisplay或者setNeedDisplayInRect:消息,或者设置其needDisplayOnBoundsChange属性为YES。

实现了displayLayer:方法的委托可以决定对于某个层应该显示哪个图像,然后相应的设置那个层的contents属性。“层坐标系”的例子中实现了displayLayer:,根据state键的值设置了theLayer的contents属性。保存state值不需要继承,因为CALayer实例可以作为一个KVC容器。

列表2 displayLayer:委托方法的样例实现

- (void)displayLayer:(CALayer *)theLayer
{
    // check the value of the layer's state key
    if ([[theLayer valueForKey:@"state"] boolValue])
    {
        // display the yes image
        theLayer.contents=[someHelperObject loadStateYesImage];
    }
    else {
        // display the no image
        theLayer.contents=[someHelperObject loadStateNoImage];
    }
}


如果你必须画层内容,而不是从一张图像加载它,你要实现drawLayer:inContext:委托方法。委托收到了需要内容的层,和用来画内容的CGContextRef。
"指定层的几何特性"的例子中实现了drawLayer:inContext:,使用theLayer返回的lineWidth键值绘制了一条路径。

列表3 drawLayer:inContent:实现的例子

- (void)drawLayer:(CALayer *)theLayer
        inContext:(CGContextRef)theContext
{
    CGMutablePathRef thePath = CGPathCreateMutable();
 
    CGPathMoveToPoint(thePath,NULL,15.0f,15.f);
    CGPathAddCurveToPoint(thePath,
                          NULL,
                          15.f,250.0f,
                          295.0f,250.0f,
                          295.0f,15.0f);
 
    CGContextBeginPath(theContext);
    CGContextAddPath(theContext, thePath );
    CGContextSetLineWidth(theContext,
                          [[theLayer valueForKey:@"lineWidth"] floatValue]);
 
    CGContextStrokePath(theContext);
 
    // release the path
    CFRelease(thePath);
}

子类化方式提供CALayer内容
虽然通常没有必要,你可以子类化CALayer并直接修改其绘图和显式方法。当层需要的自定义行为不能通过委托提供时,一般会这样做。

子类可以覆盖CALayer的display方法,将层的内容设置为相应的图像。“变换层的几何特性”的例子提供了“层坐标系”例子中委托实现的displayLayer:提供相同的功能。不同的是,子类将state定义为实例属性,而不是依赖CALayer的键值编码容器能力。

列表4 重写CALayer的display方法
- (void)display
{
    // check the value of the layer's state key
    if (self.state)
    {
        // display the yes image
        self.contents=[someHelperObject loadStateYesImage];
    }
    else {
        // display the no image
        self.contents=[someHelperObject loadStateNoImage];
    }
}



CALayer子类能通过覆盖drawInContext:来将层的内容绘制到图形环境中。"编辑变换数据结构"的例子提供了同"指定层的几何结构"例子中的委托方法实现相同的内容图片。同样,不同点是lineWidth和lineColor现在被声明成了子类的实例属性。

列表5 覆盖CALayer的drawContext:方法

- (void)drawInContext:(CGContextRef)theContext
{
    CGMutablePathRef thePath = CGPathCreateMutable();
 
    CGPathMoveToPoint(thePath,NULL,15.0f,15.f);
    CGPathAddCurveToPoint(thePath,
                          NULL,
                          15.f,250.0f,
                          295.0f,250.0f,
                          295.0f,15.0f);
 
    CGContextBeginPath(theContext);
    CGContextAddPath(theContext, thePath );
 
    CGContextSetLineWidth(theContext,
                          self.lineWidth);
 
    CGContextSetStrokeColorWithColor(theContext,
                                     self.lineColor);
    CGContextStrokePath(theContext);
    CFRelease(thePath);
}



子类化CALayer并实现某个绘图方法,并不能让绘制行为自动发生。你必须显式的让实例重新缓存内容,你可以向层发送setNeedDisplay或者setNeedDisplayInRect:消息,或者将其needDisplayOnBoundChange属性设为YES。

在层的内部定位内容

CALayer的contentsGravity允许你在层的边界内定位和缩放层的contents图像。内容图像默认填充整个层的边界,忽略图像自然的宽高比例。
使用contentsGravity定位常量,你可以指定图像沿着层的任意边缘放置,在层的四角,或者是在层边界内居中。但是,当使用定位常量时,contensCenter属性没有被使用了。表1列出了定位常量和它们相应的位置。

表1 层的contentsGravity属性的定位常量

定位常量
描述

kCAGravityTopLeft
将内容图像定位到层的左上角。

kCAGravityTop
将内容图像定位到层的上边缘的水平居中位置。

kCAGravityTopRight
将内容图像定位到层的右上角。

kCAGravityLeft
将内容图像定位到层的左边缘的垂直居中位置。

kCAGravityCenter
将内容图像定位到层的中心。

kCAGravityRight
将内容图像定位到层的右边缘的垂直居中位置。

kCAGravityBottomLeft
将内容图像定位到层的左下角。

kCAGravityBottom
将内容图像定位到层的下边缘的水平居中位置。

kCAGravityBottomRight
将内容图像定位到层的右下角。

“层坐标系”标明了所支持的内容位置和相应的常量。

图1 层的contentsGravity属性的定位常量


可以使用表2列出的常量之一设置contentsGravity属性,对内容图像进行放大或缩小。只有当contentsGravity属性使用这些常量之一进行设置时,才会影响到内容图像。

表2 层的contentsGravity的缩放常量

缩放常量
描述

kCAGravityResize
缩放内容图像以填充层边界,可能无视内容的自然比例,这是默认值。

kCAGravityResizeAspect
缩放内容图像使其竟可能占满层边界显示,但他仍然保持自然比例。

kCAGravityResizeAspectFill
缩放内容图片使其占满层显示,但仍保持自然比例。这可能导致内容超越到层边界之外。


“变换层的几何特性”表明了如何使用resizing模式,让一个正方形图像在一个矩形层内调整缩放比例。

图2 层的contentsGravity属性的缩放常量


注意:使用kCAGravityResize, kCAGravityResizeAspect和kCAGravityResizeAspectFill这几个常量之一,将导致表1中的重力定位常量无效。因为这时内容将填充层边界,不可能再使用那些常量对内容进行定位。


层树的结构(Layer-Tree Hierarchy)

原文:https://developer.apple.com/libr ... /uid/TP40006083-SW1

层除了有提供视觉和管理动画的直接责任外,也是其他层的容器,用于创建层结构。
这一章描述层的层次结构,以及在结构内如何管理众多的层。

什么是层树结构?
层树是在core animation中等同于Cocoa视图结构的东东。就像NSView或UIView的实例有超视图和子视图一样,一个core animation层有一个超层和多个子层,层树就像视图结构一样提供了很多好处:
1. 可以用更简单的层来组装复杂的界面,避免庞大和复杂的类继承。层非常适用于这类'堆叠',原因在于它们复杂的混合能力。
2.相对于超层的坐标系,每个层声明自己的坐标系。当一个层被变换,他的子层会同他一起变换。
3.层树是动态的,它可以在运行时重新配置。层可以被创建,加到一个层下面作为子层,然后被加到另外一个层,最后从层树上被删除。

在视图中显示层
core animation没有提供在窗口中实际显示层的手段,层必须附属于一个视图。当层和视图成对时,层想要提供内容显示的话,视图必须为其下的层提供事件处理。
iOS中的视图系统是直接基于于core animation的层构建的。每个UIView的实例自动创建一个CALayer的实例,并将其设置为层的layer属性。需要时可以向视图的层添加子层。

在MAC OS X上,你必须用这种方式配置一个NSView实例来拥有一个层。为了显示层树的根层,你要设置一个view的layer,然后使用表2中显示的层来配置这个视图。

列表1 向视图中插入一个层

// theView is an existing view in a window
// theRootLayer is the root layer of a layer tree
 
[theView setLayer: theRootLayer];
[theView setWantsLayer:YES];
从层次结构添加和删除层

简单的实例化一个层不能将它插入到层树中。你需要使用表1中描述的方法来添加,插入,替换和删除层。

表1 层树的管理方法

方法
结果

addSublayer:
将层追加到接受者的子层数组中。

insertSublayer:atIndex:
将层插入到接收者指定的索引位置作为子层。

insertSublayer:below:
将层插入到接受者的子层数组中,位于指定子层的下面。

insertSublayer:above:
将层插入到接受者的子层数组中,位于指定子层的上面。

removeFromSuperlayer
将接收者从子层数组中或者接收者超层的mask属性中移出。

replaceSublayer:with:
用新层替换接收者的子层数组中的层。


你也可以用层的数组设置子层,只要设置超层的sublayers属性。当用层对象的数组设置sublayer属性时,必须确保这些层的superlayer被置为nil。

默认情况下,从一个可见的层树中插入或移出层会出发动画。当层被作为子层添加,父层返回标识为kCAOrderIn动作的动画被触发。当从层的子层中移除一个层时,父层返回kCAOrderOut动作标识的动画被触发。替换子层中的一个层导致父层返回kCATransition动作标识的动画被触发。你可以在操作层树时关掉动画,或者用任何动作标识改变动画。

对层重新定位和调整大小

在层被创建后,你可以移动和调整他的大小,只需简单的改变层的几何属性:frame,bounds,position或者zPosition。
如果一个层的needsDisplayOnBoundsChange属性为YES,当层的bounds改变时层的内容将会被重新缓存。默认情况下,needsDisplayOnBoundsChange属性是NO。

默认情况下,设置frame,bounds,position,anchorPoint和zPosition属性,会让层以动画方式改变到新值。

自动调整层大小
CALayer提供了一个在超层被移动和改变大小时,自动移动子层位置和调整子层大小的机制。在多数情况下,简单的为层配置自动调整大小掩码(autoresizing mask),为应用程序提供了恰当的行为。

层的自动调整大小掩码(autoresizing mask)由CAAutoresizingMask常量指定,使用OR操作符对autoresizingMask属性进行设定。表2显示了每个掩码常量以及它如何影响层的调整大小的行为。

表2 Autoresizing mask的值和描述

Autoresizing Mask
描述

kCALayerHeightSizable
如果被设置,层的高度随超层的高度改变。否则,层的高度不随超层的高度改变。

kCALayerWidthSizable
如果被设置,层的宽度随超层的宽度改变。否则,层的宽度不随超层的宽度改变。

kCALayerMinXMargin
如果被设置,层的左边缘将随超层的宽度重新定位。否则,层的左边缘相对于超层的边缘保持相同的位置。

kCALayerMaxXMargin
如果被设置,层的右边缘将随超层的宽度重新定位。否则,层的右边缘相对于超层的边缘保持相同的位置。

kCALayerMaxYMargin
如果被设置,层的上边缘将随超层的宽度重新定位。否则,层的上边缘相对于超层的边缘保持相同的位置。

kCALayerMinYMargin
如果被设置,层的下边缘将随超层的宽度重新定位。否则,层的下边缘相对于超层的边缘保持相同的位置。
举例来说,为了让层保留在其超层的左下角,可使用kCALayerMaxXMargin | kCALayerMaxYMargin掩码。当在同轴方向上有多个活动掩码时,改变值将在它们之中均匀的分布,图1提供了这些常量值位置的图形表示。

图1 层的autoresizing mask常量


当这些常量之一被省略时,层的布局在那个方面被固定。如果一个常量出现在掩码中,那层的布局在那个方面是活动的。

层的子类可以覆盖resizeSublayersWithOldSize: 和 resizeWithOldSuperlayerSize: 方法,来自定义层的autoresizing行为。只要层的bounds属性被修改,resizeSublayersWithOldSize:将被自定调用,并发送一个resizeWithOldSuperlayerSize:消息给每一个子层。每一个子层将旧的bounds size和新的size做比较,并根据autoresizing mask调整其位置和尺寸。

剪切子层

当cocoa视图的子视图位于层边界之外时,这些视图将被父视图剪切。层去掉了这个限制,允许子层被完整的显示,而无视其在父层中的位置。
层的masksToBounds属性决定子层是否被父层所剪切。masksToBounds属性的默认值是NO,这防止了子层被父层剪切。图2显示了设置layerA的masksToBounds,以及这如何影响到layerB和layerC的显示。

图2 masksToBounds属性的取值


动画

原文: https://developer.apple.com/libr ... /uid/TP40006085-SW1

动画是当今用户界面的关键元素。当使用core animation时,动画是自动完成的。没有动画循环或者定时器。你的应用程序不必逐帧绘制或跟踪动画当前状态。动画在单独的线程自动发生,与你的应用不发生其他关系。
这一章提供了动画类的概览,并描述了如何创建显式和隐式的动画。

动画类和定时
core animation提供了一组富于表现力的动画类,你在程序中可以使用他们:
1. CABasicAnimation 为层属性提供了简单的插值。
2. CAKeyframeAnimation 提供了关键帧动画支持。你指定需要做动画的层属性的键路径,由一组值组成的数组代表动画每个阶段的值,同样可以用数组指定关键帧时间和定时含税。在动画运行过程中,每个值依次使用指定的插值设置。
3.CATransition提供了一个过度效果,能够影响整个层的内容。在动画进行时,它淡入淡出,推入和暴露层的内容。现有的过渡效果可以被扩展,你可以提供自定义的Core图像过滤器。
4. CAAnimationGroup允许一些动画对象的数组组合在一起同时运行。

除了指定要执行的动画的类型之外,你还必须指定动画的时长,步伐(在动画期间插值是如何分布的),如果动画要重复播放,则需要指定重复次数,每个循环结束时是否应该自动逆向播放,以及在动画完成时它的视觉状态。动画类和CAMediaTiming协议提供了所有这些功能,甚至更多。

CAAnimation和它的子类以及定时协议由CORE ANIMATION 和COCOA ANIMATION协议功能所共享。这些类在“动画类型和定时编程指南”里有详细的描述。

你可能感兴趣的:(数据结构,cocoa,animation,UIView,hierarchy,layer)