标签:
核心是 layer objects,
Like views, layer objects have a bounds rectangle, a position onscreen, an opacity, a transform, and many other visually-oriented properties that can be modified. 更改这些属性的时候有隐式动画,可以明确指定动画行为。
隐式layer动画是使用 action objects。可以创建自己的 action objects ,实现自定义动画,或者也能实现其他类型的行为。
先熟悉 View Programming Guide for iOS.
Layer objects 对核心。layer只是管理内容和可视化属性,所以可以将layer想成 model 对象
对于 view 中调用 drawRect:
方法,非常的损耗,因为这在线程上使用CPU。核心动画通过在硬件上缓存位图来达到同样或相似的效果。
layer 也有像view 有的一些属性,frame bounds,并且也有类似 anchor poing(锚点)这种 view 没有的属性。
point-based coordinate systems 和 unit coordinate systems
通常使用 point-based 坐标系指定 layer 的大小和位置,
unit coordinate system (单位坐标系)是用来表示当 layer 的大小变化的时候哪些属性可能改变。可以认为单位坐标系指定所有可能变化值的百分比。
Core Animation Functions Reference.
有3个 layer 对象集合:
layer 不是 view 的替代品,不能单独靠layer 对象创建一个可视化的界面。layer 提供了 view 的基础。layer 使得view内容的绘制和动画更加有效,并且动画有较高的帧率,就是更流畅。layer不能处理事件,不能绘制内容,不能参与到响应链等等。所以应用必须有一个或多个 view 来处理这种交互
重写 layerClass 类方法 返回想要替换的 类对象。
指定 view 的 layer 类
+ (Class) layerClass {
return [CAMetalLayer class];
}
CALayer子类及其用法
Class | Usage |
---|---|
3种方式给layer的位图提供数据:
将image 赋值给 layer必须是 CGImageRef 类型。
代理实现 displayLayer:
方法
- (void)displayLayer:(CALayer *)theLayer {
// Check the value of some state property
if (self.displayYesImage) {
// Display the Yes image
theLayer.contents = [someHelperObject loadStateYesImage];
}
else {
// Display the No image
theLayer.contents = [someHelperObject loadStateNoImage];
}
}
代理实现 drawLayer:inContext:
方法
- (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, 5);
CGContextStrokePath(theContext);
// Release the path
CFRelease(thePath);
}
layer 的 contentsGravity 属性模式的设置是 kCAGravityResize 常量。
iOS 不能给 layer 对象添加过滤器
精确的动画,需要创建一个 CABasicAnimation 对象,使用这个对象来配置参数。
CABasicAnimation* fadeAnim = [CABasicAnimation animationWithKeyPath:@"opacity"];
fadeAnim.fromValue = [NSNumber numberWithFloat:1.0];
fadeAnim.toValue = [NSNumber numberWithFloat:0.0];
fadeAnim.duration = 1.0;
[theLayer addAnimation:fadeAnim forKey:@"opacity"];
// Change the actual data value in the layer to the final value.
theLayer.opacity = 0.0;
// create a CGPath that implements two arcs (a bounce)
CGMutablePathRef thePath = CGPathCreateMutable();
CGPathMoveToPoint(thePath,NULL,74.0,74.0);
CGPathAddCurveToPoint(thePath,NULL,74.0,500.0,
320.0,500.0,
320.0,74.0);
CGPathAddCurveToPoint(thePath,NULL,320.0,500.0,
566.0,500.0,
566.0,74.0);
CAKeyframeAnimation * theAnimation;
// Create the animation object, specifying the position property as the key path.
theAnimation=[CAKeyframeAnimation animationWithKeyPath:@"position"];
theAnimation.path=thePath;
theAnimation.duration=5.0;
// Add the animation to the layer.
[theLayer addAnimation:theAnimation forKey:@"position"];
removeAnimationForKey:
removeAllAnimations
只能移除显示动画,不能移除隐式动画。
// Animation 1
CAKeyframeAnimation* widthAnim = [CAKeyframeAnimation animationWithKeyPath:@"borderWidth"];
NSArray* widthValues = [NSArray arrayWithObjects:@1.0, @10.0, @5.0, @30.0, @0.5, @15.0, @2.0, @50.0, @0.0, nil];
widthAnim.values = widthValues;
widthAnim.calculationMode = kCAAnimationPaced;
// Animation 2
CAKeyframeAnimation* colorAnim = [CAKeyframeAnimation animationWithKeyPath:@"borderColor"];
NSArray* colorValues = [NSArray arrayWithObjects:(id)[UIColor greenColor].CGColor,
(id)[UIColor redColor].CGColor, (id)[UIColor blueColor].CGColor, nil];
colorAnim.values = colorValues;
colorAnim.calculationMode = kCAAnimationPaced;
// Animation group
CAAnimationGroup* group = [CAAnimationGroup animation];
group.animations = [NSArray arrayWithObjects:colorAnim, widthAnim, nil];
group.duration = 5.0;
[myLayer addAnimation:group forKey:@"BorderChanges"];
There are two different ways to be notified about the state of an animation:
[UIView animateWithDuration:1.0 animations:^{
// Change the opacity implicitly.
myView.layer.opacity = 0.0;
// Change the position explicitly.
CABasicAnimation* theAnim = [CABasicAnimation animationWithKeyPath:@"position"];
theAnim.fromValue = [NSValue valueWithCGPoint:myView.layer.position];
theAnim.toValue = [NSValue valueWithCGPoint:myNewPosition];
theAnim.duration = 3.0;
[myView.layer addAnimation:theAnim forKey:@"AnimateFrame"];
}];
myLayer.bounds = CGRectMake(0, 0, 100, 100);
myLayer.position = CGPointMake(200, 200);
重点:对于 layer 的宽高总是使用整数
speed 属性,动画速度的倍数。
Core Animation supports several options for adjusting the size and position of sublayers in response to changes to their superlayer. In iOS, the pervasive use of layer-backed views makes the creation of layer hierarchies less important; only manual layout updates are supported. For OS X, several other options are available that make it easier to manage your layer hierarchies
masksToBounds 属性设置 YES,就可以启用自动裁剪
还有 convertTime:fromLayer 和 convertTime:toLayer
创建 CATransition 对象 ,并添加给 layer。
Listing 5-1 shows the code used to create an animated push transition between two views. In the example, both myView1 and myView2 are located at the same position in the same parent view but only myView1 is currently visible. The push transition causes myView1 to slide out to the left and fade until it is hidden while myView2 slides in from the right and becomes visible. Updating the hidden property of both views ensures that the visibility of both views is correct at the end of the animation.
CATransition* transition = [CATransition animation];
transition.startProgress = 0;
transition.endProgress = 1.0;
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromRight;
transition.duration = 1.0;
// Add the transition animation to both layers
[myView1.layer addAnimation:transition forKey:@"transition"];
[myView2.layer addAnimation:transition forKey:@"transition"];
// Finally, change the visibility of the layers.
myView1.hidden = YES;
myView2.hidden = NO;
CAMediaTiming 协议。CAAnimation
和 CALayer
都遵守了这个协议。
#import <QuartzCore/CABase.h>
#import <objc/objc.h>
#import <Foundation/NSObject.h>
/* The CAMediaTiming protocol is implemented by layers and animations, it
* models a hierarchical timing system, with each object describing the
* mapping from time values in the object‘s parent to local time.
*
* Absolute time is defined as mach time converted to seconds. The
* CACurrentMediaTime function is provided as a convenience for querying the
* current absolute time.
*
* The conversion from parent time to local time has two stages:
*
* 1. conversion to "active local time". This includes the point at
* which the object appears in the parent‘s timeline, and how fast it
* plays relative to the parent.
*
* 2. conversion from active to "basic local time". The timing model
* allows for objects to repeat their basic duration multiple times,
* and optionally to play backwards before repeating. */
@class NSString;
NS_ASSUME_NONNULL_BEGIN
@protocol CAMediaTiming
/* The begin time of the object, in relation to its parent object, if
* applicable. Defaults to 0. */
@property CFTimeInterval beginTime;
/* The basic duration of the object. Defaults to 0. */
@property CFTimeInterval duration;
/* The rate of the layer. Used to scale parent time to local time, e.g.
* if rate is 2, local time progresses twice as fast as parent time.
* Defaults to 1. */
@property float speed;
/* Additional offset in active local time. i.e. to convert from parent
* time tp to active local time t: t = (tp - begin) * speed + offset.
* One use of this is to "pause" a layer by setting `speed‘ to zero and
* `offset‘ to a suitable value. Defaults to 0. */
@property CFTimeInterval timeOffset;
/* The repeat count of the object. May be fractional. Defaults to 0. */
@property float repeatCount;
/* The repeat duration of the object. Defaults to 0. */
@property CFTimeInterval repeatDuration;
/* When true, the object plays backwards after playing forwards. Defaults
* to NO. */
@property BOOL autoreverses;
/* Defines how the timed object behaves outside its active duration.
* Local time may be clamped to either end of the active duration, or
* the element may be removed from the presentation. The legal values
* are `backwards‘, `forwards‘, `both‘ and `removed‘. Defaults to
* `removed‘. */
@property(copy) NSString *fillMode;
@end
/* `fillMode‘ options. */
CA_EXTERN NSString * const kCAFillModeForwards
__OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
CA_EXTERN NSString * const kCAFillModeBackwards
__OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
CA_EXTERN NSString * const kCAFillModeBoth
__OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
CA_EXTERN NSString * const kCAFillModeRemoved
__OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
NS_ASSUME_NONNULL_END
得到 layer 的当前 local time
CFTimeInterval localLayerTime = [myLayer convertTime:CACurrentMediaTime() fromLayer:nil];
-(void)pauseLayer:(CALayer*)layer {
CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
layer.speed = 0.0;
layer.timeOffset = pausedTime;
}
-(void)resumeLayer:(CALayer*)layer {
CFTimeInterval pausedTime = [layer timeOffset];
layer.speed = 1.0;
layer.timeOffset = 0.0;
layer.beginTime = 0.0;
CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
layer.beginTime = timeSincePause;
}
创建显式的 transaction
[CATransaction begin];
theLayer.zPosition=200.0;
theLayer.opacity=0.0;
[CATransaction commit];
修改动画的默认持续时间
[CATransaction begin];
[CATransaction setValue:[NSNumber numberWithFloat:10.0f]
forKey:kCATransactionAnimationDuration];
// Perform the animations
[CATransaction commit];
嵌套显式 transaction
[CATransaction begin]; // Outer transaction
// Change the animation duration to two 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 five 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
给 parent layer 添加透视变化
CATransform3D perspective = CATransform3DIdentity;
perspective.m34 = -1.0/eyePosition;
// Apply the transform to a parent layer.
myParentLayer.sublayerTransform = perspective;
CAAction 协议
/** Action (event handler) protocol. **/
@protocol CAAction
/* Called to trigger the event named ‘path‘ on the receiver. The object
* (e.g. the layer) on which the event happened is ‘anObject‘. The
* arguments dictionary may be nil, if non-nil it carries parameters
* associated with the event. */
- (void)runActionForKey:(NSString *)event object:(id)anObject
arguments:(nullable NSDictionary *)dict;
@end
核心动画寻找 action 对象的顺序:
actionForLayer:forKey
方法,layer调用这个方法。delegate 必须做下面几件事之一: style
字典包含了一个 key 为 actions
,value 也是一个字典。layer 在这第二个字典中寻找给定的 key)使用 layer 代理对象提供 action
- (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;
}
Temporarily disabling a layer’s actions
[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue
forKey:kCATransactionDisableActions];
[aLayer removeFromSuperlayer];
[CATransaction commit];
Layer Style Property Animations
核心动画编程指南Core Animation Programming Guide - iOS
标签:
原文地址:http://blog.csdn.net/zyq522376829/article/details/52456981