Core Animation学习指南

写完这篇博文感受特别的累,所以我推荐的学习方法是,先将这些知识存放到一个地方,然后了解清楚,之后再去做相关方面的demo,在demo中学习

最近几天一直都在学习关于Core Animation的内容,但是在cocosChina上找到的是很老版本了,与如今的差距太大,后来终于找到了一个核心动画编程,又在每一个博客上不断的学习,所以今天就对这几天的学习做一个总结,也方便以后的继续学习。可以结合这核心动画编程这本pdf来学习,稍后会给链接

在图层中,frame的origin是在左下角的地方,并不是uiview的一样。宽高是一样的。关于锚点和position之间的关系 之前已经博文上已经写过了,这里不做说明。

图层的几何变换  图层一旦创建 你就可以通过矩阵变换来改变一个图层的几何形状 CATransform3D .

CATransform3D的数据结构 定义一个同质的三维变换 用于图层的旋转 缩放 偏移 歪斜 和应用的透视 。

struct CATransform3D
{
CGFloat m11(x缩放), m12(y切变), m13(), m14();
CGFloat m21(x切变), m22(y缩放), m23(), m24();
CGFloat m31(), m32(), m33(), m34(透视效果,要操作的这个对象要有旋转的角度,否则没有效果。当然,z方向上得有变化才会有透视效果);
CGFloat m41(x平移), m42(y平移), m43(z平移), m44();
};

当前3d就不去做谈论了 以后学习的时候再去做深入的学习

CATransform3DIdentity 

是单位矩阵,该矩阵没有缩放、旋转、歪斜、透视。把该 矩阵应用到图层上面,会把图层几何属性修改为默认值。 

 

接下来就是学习图层的知识

基础知识了解:

每个 UIView 的实例会自 动的创建一个 CALayer 类的实例,然后把该实例赋值给视图的 layer 属性 

图层的插入和替换和删除图层

   
addSublayer:

Appends the layer to the receiver’s sublayers array.

insertSublayer:atIndex:

Inserts the layer as a sublayer of the receiver at the specified index.

insertSublayer:below:

Inserts the layer into the receiver’s sublayers array, below the specified sublayer.

insertSublayer:above:

Inserts the layer into the receiver’s sublayers array, above the specified sublayer.

removeFromSuperlayer

Removes the receiver from the sublayers array or mask property of the receiver’s superlayer.

replaceSublayer:with:

Replaces the layer in the receiver’s sublayers array with the specified new layer.

 

 

 

自动调整图层大小

CALayer 提供了一个机制,在父图层被移动或者改变大小的时候,子图层可以自 动的跟着移动和调整大小。在很多情况下简单的配置一个图层的自动调整掩码 (autoresizing mask)可以适当的适应程序的行为。 

里面有许多类似

kCALayerMaxXMargin  kCALayerMaxYMargin 的常量,这些其实就是指明当前图层可以适应其父图层的x或者y方向,就是可以自动调整大小,这一块可以跟随着我提供的附件一起学习。

 

对于CALayer的子类 可以重写

resizeSublayersWithOldSize: 和 resizeWithOldSuperlayerSize:来定制化的自动调整图层大小的行为   图层的函数 resizeSublayersWithOldSize:将会在 bounds 属性被修改的时候自动的触发执行,同时 发送一个消息 resizeWithOldSuperlayerSize:给图层的每个子图层。图层的每个子图层 根据自动调整掩码的属性来比较就的边界值和新的边界值来调整它的位置和大小。 

 

图层的 masksToBounds 属性决定了是否子图层是否相对父图层裁剪。该属性 masksToBounds 的默认值为 NO,即防止子图层被相对于父图层裁剪 

 

提供图层内容

你可以通过以下任何一种方法指定 CALayer 实例的内容:
使用包含图片内容的 CGImageRef 来显式的设置图层的 contents 的属性。

指定一个委托,它提供或者重绘内容。

继承 CALayer 类重载显示的函数。 

 

图层的图片内容可以通过指定 contents 属性的值为 CGImageRef   代码例子会附在之后的链接上一起打包

当图层被创建 的时候或者在任何其他时候,这个操作可以在其他实体上面完成 

通过委托提供内容 

你可以绘制图层的内容,或更好的封装图层的内容图片,通过创建一个委托类实 

现下列方法之一:

displayLayer:或 drawLayer:inContext:

实现委托重绘的方法并不意味会自动的触发图层使用实现的方法来重绘内容。而 是你要显式的告诉一个图层实例来重新缓存内容,通过发送以下任何一个方法 setNeedsDisplay 或 者 setNeedsDisplayInRect: 的 消 息 , 或 者 把 图 层 的 needsDisplayOnBoundsChange 属性值设置为 YES。 

通过委托实现方法 displayLayer:可以根据特定的图层决定显示什么图片,还可以 更加需要设置图层的 contents 属性值。下面的例子是“图层的坐标系”部分的,它实 现 displayerLayer:方法根据 state 的值设置 theLayer contents 属性。子类不需要存储 state 的值,因为 CALayer 的实例是一个键-值编码容器。 

 (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];

}

}


  所谓的键值编码  就是对layer  setvalue:forkey;

根据value值去做不同的事情。

 

如果你必须重绘图层的内容,而不是通过加载图片,那你需要实现 drawLayer:inContext:方法。通过委托可以决定哪些内容是需要的并使用 CGContextRef 来重绘内容。

下面的例子是“指定图层的几何”部分内容,它实现了 drawLayer:inContext:方 法使用 lineWidth 键值来重绘一个路径(path),返回 therLayer。 

  

 (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 的显示方法,设置图层的内容为适当的图片。下面的例子 是“变换图层的几何”部分的内容,它提供了和“图层的坐标系”例子相同的功能。 不同的是子类定义 state 为实例的属性,而不是根据 CALayer 的键-值编码容器获取。 


- (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 并且实现其中的重绘方法并不意味重绘会自动发生。你必须显式的 促使实例重新缓存其内容,可以通过发送以下任何一个方法 setNeedsDisplay setNeedsDisplayInRect:的消息,亦或者设置图层的 needsDisplaOnBoundsChange 属性 为 YES。 

  

 

CALayer 子类可以通过重载 drawInContext:绘制图层的内容到一个图形上下文。 下面的例子是“修改变换的数据结构”的内容,它和“指定图层的几何”里面实现委 托的办法一样产生相同的图片内容。唯一的不同的是实现委托里面的 lineWidth lineColor 现在是子类实例的属性。 

 

 修改图层内容的位置

CALayer的属性contentsGravity允许你在图层的边界内容修改图层的contents图片的位置或者伸缩值。默认情况下,内容的图像完全填充层的边界,忽视自然的图像宽高比。
使用contentsGravity位置常量,你可以指定图片位于图层任何一个边界,比如位于图层的角落,或者图层边界的中心。然而当你使用位置常量的时候,contentsCenter属性会被忽略。表1列举了位置常量和他们相应的位置。

 

通过设置contentsGravity属性为其他一个常量(如表2所示)。图层的内容图片可以被向上或者向下拉伸, 仅当使用其他任何一个调整大小的常量的时候,contentsCenter属性才会对内容图片起作用。

使用任何常量kCAGravityResize、kCAGravityResizeAspect和kCAGravityResizeAspectFill和表1中的重心位置常量无关。图层的内容将会填充整个边界,所以使用这些常量无法改变图层内容的位置。

 

动画

核心动画提供了一套你可以在你应用程序里面使用的动画类的表现:
􀂄
CABasicAnimation提供了在图层的属性值间简单的插入。
􀂄
CAKeyframeAnimation提供支持关键帧动画。你指定动画的一个图层属性的关键路径,一个表示在动画的每个阶段的价值的数组,还有一个关键帧时间的数组和时间函数。
􀂄
CATransition提供了一个影响整个图层的内容过渡效果。在动画显示过程中采用淡出(fade)、推出(push)、显露(reveal)图层的内容。 常用的过渡效果可以通过提供你自己定制的核心图像滤镜来扩展。

对于上边三个类对象  可以在网上搜索其相关方面的教程 然后去学习

隐式动画

核心动画的隐式动画模型假定所有动画图层属性的变化应该是渐进和异步的。动态的动画场景 可以在没有显示的动画图层时候实现(如果有动画图层就可能会没有效果)。

改变动画显示的图层的属性将会导致图层隐式把图层从旧的值动画的显示为新的值,虽然动画是持续的,但是设置新的目标值时会导致图层从当前状态动画过度的新的目标。

theLayer.position=CGPointMake(500.0,500.0);

  你可以隐式的一次动画改变图层的一个或者多个属性。你还可以隐式的同时动画改变多个图层。清单2的代码实现了4个同时触发的隐式动画。

 

// animate theLayer's opacity to 0 while moving it
// further away in the layer
theLayer.opacity=0.0;
theLayer.zPosition=-100;
// animate anotherLayer's opacity to 1
// while moving it closer in the layer
anotherLayer.opacity=1.0;
anotherLayer.zPosition=100.0;

 隐式动画使用动画属性中默认指定的动画时间,除非该时间已经被隐式或者显式的修改过。阅读“重载覆盖隐式动画时间”获取更多详情。

 

显式动画

 

核心动画同时提供了一个显式的动画模型。该显式动画模型需要你创建一个动画对象,并设置开始和结束的值。显式动画不会开始执行,直到你把该动画应用到某个图层上面

代码片段创建了一个显式动画,它实现一个层的不透明度从完全不透明过渡到完全透明的,3秒后返回重新执行。动画没有开始,直到它被添加到某一图层层。

 

CABasicAnimation *theAnimation;
theAnimation=[CABasicAnimation animationWithKeyPath:@"opacity"];(创建一个关于透明度的动画)

theAnimation.duration=3.0;
theAnimation.repeatCount=2;
theAnimation.autoreverses=YES;
theAnimation.fromValue=[NSNumber numberWithFloat:1.0];
theAnimation.toValue=[NSNumber numberWithFloat:0.0];
[theLayer addAnimation:theAnimation forKey:@"animateOpacity"];

 

  创建一个显式动画,把一个CoreImage滤镜应用到图层上面,动画显示其强度。这将导致“选择的图层”跳动,吸引用户的注意力。

CIFilter是core image的滤镜效果,这里先不作学习

CIFilter *filter = [CIFilter filterWithName:@"CIBloom"];
[filter setDefaults];
[filter setValue:[NSNumber numberWithFloat:5.0] forKey:@"inputRadius"];
// name the filter so we can use the keypath to animate the inputIntensity
// attribute of the filter
[filter setName:@"pulseFilter"];
// set the filter to the selection layer's filters
[selectionLayer setFilters:[NSArray arrayWithObject:filter]];
// create the animation that will handle the pulsing.
CABasicAnimation* pulseAnimation = [CABasicAnimation animation];

// the attribute we want to animate is the inputIntensity
// of the pulseFilter
pulseAnimation.keyPath = @"filters.pulseFilter.inputIntensity";

// we want it to animate from the value 0 to 1
pulseAnimation.fromValue = [NSNumber numberWithFloat: 0.0];
pulseAnimation.toValue = [NSNumber numberWithFloat: 1.5];
// over a one second duration, and run an infinite
// number of times
pulseAnimation.duration = 1.0;
pulseAnimation.repeatCount = HUGE_VALF;
// we want it to fade on, and fade off, so it needs to
// automatically autoreverse.. this causes the intensity
// input to go from 0 to 1 to 0
pulseAnimation.autoreverses = YES;

// use a timing curve of easy in, easy out..
pulseAnimation.timingFunction = [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseInEaseOut];
// add the animation to the selection layer. This causes
// it to begin animating. We'll use pulseAnimation as the
// animation key name
[selectionLayer addAnimation:pulseAnimation forKey:@"pulseAnimation"];

  

开始和结束显式动画

你可以发送addAnimation:forKey:消息给目标图层来开始一个显式动画,把动画和标识符作为参数。一旦把动画添加到目标图层,动画将会一直执行直到动画完成,或者动画被从图层上面移除。把动画添加到图层时添加的标识符,同样也可以在停止动画的时候使用,通过调用removeAnimationForKey:。你可以通过给图层发送一个removeAllAnimations消息来停止图层所有的动画。

 

图层的行为

图层的行为在以下情况发生的时候被触发:从图层树里面插入或者删除一个图层,图层的属性值被修改了,或者程序显式要求。通常情况下,行为触发器是动画显示的结果所在。

行为对象的角色(在下边的学习中有的问题比较难,所以只是罗列一下它的情况,并不去具体的学习,本篇博文的主要目标就是能够使我们在遇到这些技术难点的时候知道它是什么,这样我们就可以根据技术难点具体的学习)

 

一个行为对象是一个通过CAAction协议响应行为标识符的对象。行为标识符使用标准圆点分隔的关键路径来命名。图层负责把行为标识符映射到特定的行为对象。当一个特定标识符的行为对象被确定的时候,它会发送一个CAAction协议定义的消息。
CALayer类提供了默认的CAAnimation的行为对象实例,一个兼容类所有动画层属性CAAction协议。表1中CALayer同样定义了以下没有直接对应到属性的行为触发器和他们的行为标识符。

已定义搜索模式的行为键值

当一个行为触发器发生的时候,图层的actionForKey:方法被调用。此方法返回一个行为对象,对应的标识符作为参数,或如果行为对象不存在的话返回nil。
当CALayer为一个标识符实现的actionForKey:方法被调用的时候,以下的搜索模式将会被用到:
1. 如
果一个图层有委托,那方法actionForLayer:forKey:的实现将会被调用,把图层和行为标识符作为参数。委托的actionForLayer:forKey:的实现需要响应如下:

􀁺
返回一个行为标识符对应的行为对象。
􀁺
返回nil,当无法处理行为标识符的时候。
􀁺
返回NSNull,当无法处理行为标识符,而且搜索需要被终止的时候。
2. 图
层的actions字典被搜索以便找到一个和行为标识符对应的对象。
3. 图
层的style属性被搜索以便找到一个包含行为标识符的actions字典。
4. 图
层类发生一个defaultActionForKey:的消息。它将会返回一个和标识符对应的行为对象,如果不存在的话则返回nil。

 

 

采用CAAction协议

CAAction协议定义了行为对象如何被调用。实现CAAction协议的类包含一个方法runActionForKey:object:arguments:。
当行为对象收到一个runActionForKey:object:arguments:的消息时,行为标识符、行为发生所在的图层、额外的参数字典会被作为参数传递给方法。
通常行为对象是CAAnimation的子类实例,它实现了CAAction协议。然而你也可以返回任何实现了CAAction协议的类对象。当实例收到runActionForKey:object:arguments:的消息时,它需要执行相应的行为。
当CAAnimation实例受到消息runActionForKey:object:arguments:的时候,它把自己添加到图层的动力里面,触发动画的执行(查看清单1)。

- (void)runActionForKey:(NSString *)key
object:(id)anObject
arguments:(NSDictionary *)dict
{
[(CALayer *)anObject addAnimation:self forKey:key];
}

  重载隐式动画

你可以为行为标识符提供隐式的动画,通过插入一个CAAnimation的实例到style字典里面的actions的字典里面,通过实现委托方法actionForLayer:forKey:或者继承

图层类并重载defaultActionForKey:方法返回一个相应的行为对象。
清单2的示例通过委托替换contents属性的隐式动画。

- (id<CAAction>)actionForLayer:(CALayer *)theLayer
forKey:(NSString *)theKey
{
CATransition *theAnimation=nil;
if ([theKey isEqualToString:@"contents"])
{
theAnimation = [[CATransition alloc] init];
theAnimation.duration = 1.0;
theAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
theAnimation.type = kCATransitionPush;
theAnimation.subtype = kCATransitionFromRight;
}
return theAnimation;
}

  

// get a mutable version of the current actions dictionary
NSMutableDictionary *customActions=[NSMutableDictionary dictionaryWithDictionary:[theLayer actions]];
// add the new action for sublayers
[customActions setObject:[NSNull null] forKey:@"sublayers"];
// set theLayer actions to the updated dictionary
theLayer.actions=customActions;

 事务

 

图层的每个改变都是事务的一部分。CATransaction是核心动画类,它负责成批的把多个图层树的修改作为一个原子更新到渲染树。
本章介绍了核心动画支持的两种事务。隐式事务和显式事务。

隐式事务

当图层树被没有获得事务的线程修改的时候将会自动创建隐式事务,当线程的运行循环(run-loop)执行下次迭代的时候将会自动提交事务。
清单1的示例修改图层的opacity,zPosition和position数字,依赖隐式事务来确保动画同时一起发生。

theLayer.opacity=0.0;
theLayer.zPosition=-200;
thelayer.position=CGPointMake(0.0,0.0);

  重要:当在一个没有运行循环(runloop)的线程修改图层的属性的时候,你必须使用显式的事务。

 

显式事务

在你修改图层树之前,可以通过给CATransaction类发送一个begin消息来创建一个显式事务,修改完成之后发送comit消息。显式事务在同时设置多个图层的属性的时候(例如当布局多个图层的时候),暂时的禁用图层的行为,或者暂时修改动画的时间的时候非常有用。

暂时禁用图层的行为

你可以在修改图层属性值的时候通过设置事务的kCATransactionDisableActions值为YES来暂时禁用图层的行为。在事务范围所作的任何更改也不会因此而发生的动画。清单2显示了一个示例,当把aLayer从可视化图层树移除的时候禁用淡出动画。

 

[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue
forKey:kCATransactionDisableActions];
[aLayer removeFromSuperlayer];
[CATransaction commit];

  重载隐式动画的时间

你可以暂时改变响应改变图层属性的动画的时间,通过设置事务的kCATransactionAnimationDuration键的值为新的时间。事务范围内所产生的任何动画都会使用该新设置的时间值而不是他们原有的值。清单3显示了一个示例,把动画的发生时间改为10秒而不是zPosition和opacity所指定的动画的默认时间。

[CATransaction begin];
[CATransaction setValue:[NSNumber numberWithFloat:10.0f]
forKey:kCATransactionAnimationDuration];
theLayer.zPosition=200.0;
theLayer.opacity=0.0;
[CATransaction commit];

  即使上面的示例中显示了begin和commit所包围的显式事务的时间,你也可以忽略这些而采用隐式事务来替代。

事务的嵌套

显式事务可以被嵌套,允许你禁用部分动画的行为或者在属性被修改的时候产生的动画使用不同的时间。仅当最外层的事务被提交的时候,动画才会发生。
清单4 中显示了一个嵌套两个事务的例子。最外层的事务设置隐式动画的时间为2秒,并设置图层的position属性值。内层的事务设置隐式动画的时间为5秒,并修改图层的opacity和zPosition属性值。

[CATransaction begin]; // outer transaction

// change the animation duration to 2 seconds
[CATransaction setValue:[NSNumber numberWithFloat:2.0f]
forKey:kCATransactionAnimationDuration];
// move the layer to a new position
theLayer.position = CGPointMake(0.0,0.0);
[CATransaction begin]; // inner transaction
// change the animation duration to 5 seconds
[CATransaction setValue:[NSNumber numberWithFloat:5.0f]
forKey:kCATransactionAnimationDuration];
// change the zPosition and opacity
theLayer.zPosition=200.0;
theLayer.opacity=0.0;

[CATransaction commit]; // inner transaction
[CATransaction commit]; // outer transaction

  

布局核心动画的图层

NSView提供了经典的“stuts and springs”模式,用于视图调整大小的时候把关联到它父图层的视图重新调整位置。图层支持该模式,而且Mac OS X上面的核心动画提供了一个更通用的布局管理器机制,允许开发者自己写他们自己的布局管理器。可以为图层定制一个布局管理器(它通常实现CALayoutManager协议),负责给图层的子图层提供布局功能。
本章介绍了约束布局管理器和如何配置一系列约束条件。
iOS 注意:iOS的CALayer类仅提供“stuts and springs”模式,不提供定制的布局管理器。然而如果你想人工修改关联到特别视图的图层的位置的话,你可以重载相应视图的layoutSubviews方法,在这里面实现你定制的布局代码。你可以查看“iOS视图编程指南(View Programming Guide for iOS)”来获取更多关于如何在iOS应用里面基于视图的布局方法。

约束布局管理器

基于条件的布局允许你根据图层和它同级图层或者它的父图层的相应关系指定图层的位置和大小。通过CAConstraint类描述的关系被保存在子图层的constraints数组属性里面。

当使用约束布局的时候,你首先创建一个CAConstraintLayoutManager的实例,并把它设置为父图层的布局管理器。然后你通过实例化CAConstraint对象为子图层创建约束条件,并把这些约束条件通过使用addConstraint:方法添加到子图层的约束属性里面。每个CAConstraint实例封装了一个两个图层在同一轴上的几何关系。
同级层引用的名称,使用图层的name属性。特定的名称superlayer被使用来引用图层的父图层。
每个轴上面最多只能指定两个关系。如果你给图层的左边和右边都指定约束关系,那么图层的宽度就会不同。如果你给图层的左边和宽度指定约束关系,则图层的右边就会从根据父图层的frame移动。通常你一般只会指定单个边的约束条件,图层在同一个轴上面的大小将会作为第二个约束关系。
清单1里面的示例代码创建了一个图层,然后使用位置约束条件添加子图层。图2描述了布局的结果。

// create and set a constraint layout manager for theLayer
theLayer.layoutManager=[CAConstraintLayoutManager layoutManager];
CALayer *layerA = [CALayer layer];
layerA.name = @"layerA";

layerA.bounds = CGRectMake(0.0,0.0,100.0,25.0);
layerA.borderWidth = 2.0;
[layerA addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMidY
relativeTo:@"superlayer"
attribute:kCAConstraintMidY]];
[layerA addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMidX
relativeTo:@"superlayer"
attribute:kCAConstraintMidX]];
[theLayer addSublayer:layerA];

CALayer *layerB = [CALayer layer];
layerB.name = @"layerB";
layerB.borderWidth = 2.0;
[layerB addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintWidth
relativeTo:@"layerA"
attribute:kCAConstraintWidth]];
[layerB addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMidX
relativeTo:@"layerA"
attribute:kCAConstraintMidX]];

[layerB addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMaxY
relativeTo:@"layerA"
attribute:kCAConstraintMinY
offset:-10.0]];
[layerB addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMinY

relativeTo:@"superlayer"
attribute:kCAConstraintMinY
offset:+10.0]];
[theLayer addSublayer:layerB];

  

以上是代码执行过程:
1. 创
建一个CAConstraintLayoutmanager实例,然后把它设置为theLayer的layoutManger的属性。
2. 创
建一个CALayer(layerA)的实例,设置图层的name属性为“layerA”。
3. 设
置layerA的bounds为(0.0,0.0,10.0,25.0)。
4. 创
建一个CAConstraint对象,把它作为约束条件添加到layerA里面。该约束条件是把layerA的水平中心对齐它的父图层的水平中心。
5. 创
建第二个CAConstraint对象,把它作为layerA的约束条件。该约束条件是把layerA的垂直中心对齐父图层的垂直中心。
6. 把
layerA添加为theLayer的子图层。
7. 创
建一个CALayer(layerB)的实例,设置图层的name属性为“layerB”。

8. 创
建一个CAConstraint对象,给layerA添加该约束条件,该约束条件是设置layerB的宽度设置为与layerA的宽度相同。
9. 创
建第二个CAConstraint对象,把该约束条件添加到layerB里面。该约束条件是设置layerB的水平中心对齐layerA的水平中心。
10. 创建
第三个CAConstraint对象,并把它添加为layerB的约束条件。该约束条件设置layerB的顶边低于layerA底边10像素。
11. 创建
第四个CAConstraint对象,把它作为约束条件添加到layerB里面。该约束条件是把layerB的底边高于父图层底边10像素。
注意: 有可能创建约束条件导致在相同的属性的循环引用。在布局是无法计算的情况下,行为结果是不可预知的。

之后的内容都是在核心动画编程指南里,太多了,这里就不写了,相信在应用的时候能够知道是什么并能通过学习去掌握

:http://download.csdn.net/detail/chenscda/7117975

posted on 2014-03-29 16:18  chenhanqing_blcu  阅读(330)  评论(0编辑  收藏  举报