Core animation taobao

Preview:

Citation preview

Core Animation for iOS孔祥波 @yarshure

11年7月12日星期二

自我介绍

FreeBSD 用户

摄影爱护者

就职盛大创新院

11年7月12日星期二

11年7月12日星期二

11年7月12日星期二

11年7月12日星期二

Mee Code

11年7月12日星期二

11年7月12日星期二

11年7月12日星期二

11年7月12日星期二

WWDC08 Session 711 演示

11年7月12日星期二

CoverFlow特效

11年7月12日星期二

什么是Core Animation?

• Objc Class: graphics rendering, projection, and animation

• provides fluid animations

• provide with Leopard

11年7月12日星期二

Why use Core Animation?

• High performance compositing with a simple approachable programming model

• create complex user interfaces using a hierarchy of layer objects

• A lightweight data structure

• allows animations to run on a separate thread

• Improved application performance

• A flexible layout manager model

11年7月12日星期二

• UIView Animation

• UIImageView Animation

Basic Animation

11年7月12日星期二

UIView Animation-(void)beginAnimation{ [UIView beginAnimations:@”uiviewanimiton” context:nil]; [UIView setAnimationDuration:0.125]; [UIView setAnimationDelegate:self]; [UIView setAnimationWillStartSelector:@selector(beginAnimations:context:)]; [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)]; CGPoint center=CGPointMake(header.center.x,header.center.y+75); header.center=center; [UIView commitAnimations];}

11年7月12日星期二

Delegate

• -animationWillStart:(NSString *)animationID context:(void *)context

• -animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context

11年7月12日星期二

- (void)setSelectedVeg:(id)sender{ [selectedVegetableIcon setAlpha:0.0]; [UIView animateWithDuration:0.4 animations: ^{ float angle = [self spinnerAngleForVegetable:sender]; [vegetableSpinner setTransform:CGAffineTransformMakeRotation(angle)]; } completion:^(BOOL finished) { [selectedVegetableIcon setAlpha:1.0]; }]; }以上代码来自WWDC2010 iPlant PlantCareViem.m

使用Block

11年7月12日星期二

UIImageView Animation imageArray = [[NSMutableArray alloc] initWithCapacity:IMAGE_COUNT]; for (int i = 0; i < IMAGE_COUNT; i++) [imageArray addObject:[UIImage imageNamed:[NSString stringWithFormat:@"Frame_%d.jpg", i]]]; animatedImages = [[UIImageView alloc] initWithFrame:CGRectMake( (SCREEN_WIDTH / 2) - (IMAGE_WIDTH / 2), (SCREEN_HEIGHT / 2) - (IMAGE_HEIGHT / 2) + STATUS_BAR_HEIGHT, IMAGE_WIDTH, IMAGE_HEIGHT)]; animatedImages.animationImages = [NSArray arrayWithArray:imageArray]; animatedImages.animationDuration = 1.0; animatedImages.animationRepeatCount = -1; // Start it up [animatedImages startAnimating]; // Wait 5 seconds, then stop animation [self performSelector:@selector(stopAnimation) withObject:nil afterDelay:5.0];停止方法:-(void)stopAnimation{ [animatedImages stopAnimating];}

11年7月12日星期二

Core Animation

NSObjectCaAnimation

<CAAction,CAMediaTiming>

CALayer<CAMediaTiming>

CAMediaTimingFuncation

CATransaction

CaAnimationGroup

CAPropertyAnimationn

CATransition

CABasicAnimationn

CAKeyframeAnimationn

CAScrollLayer

CATiledLayer

CATextLayer

CAEAGLLayer

CAEmitterLayer(iOS5)

11年7月12日星期二

CATransaction

• CATransaction is the Core Animation mechanism for batching multiple layer-tree operations into atomic updates to the render tree.

• Every modification to a layer tree must be part of a transaction. Nested transactions are supported.

• customize duration, timing function

11年7月12日星期二

CATransactionImplicit transactionstheLayer.opacity=0.0;

theLayer.zPosition=-200;

thelayer.position=CGPointMake(0.0,0.0);

Explicit Transactions[CATransaction begin];

[CATransaction setValue:(id)kCFBooleanTrue

forKey:kCATransactionDisableActions];

[aLayer removeFromSuperlayer];

[CATransaction commit];

11年7月12日星期二

CATransaction(Nested)[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 positiontheLayer.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

11年7月12日星期二

- (void)layoutContents{ // layoutContents gets called via KVO whenever properties within our oalPlayback object change // Wrap these layer changes in a transaction and set the animation duration to 0 so we don't get implicit animation [CATransaction begin]; [CATransaction setValue:[NSNumber numberWithDouble:0.]

forKey:kCATransactionAnimationDuration]; // Position and rotate the listener _listenerLayer.position = playback.listenerPos; _listenerLayer.transform = CATransform3DMakeRotation(playback.listenerRotation, 0., 0., 1.); // The speaker gets rotated so that it's always facing the listener CGFloat rot = atan2(-(playback.sourcePos.x - playback.listenerPos.x), playback.sourcePos.y - playback.listenerPos.y); // Rotate and position the speaker _speakerLayer.position = playback.sourcePos; _speakerLayer.transform = CATransform3DMakeRotation(rot, 0., 0., 1.); void (^transactionEnd)(void); transactionEnd = ^(void) { NSLog(@"from opt"); };

[CATransaction setValue:oneFrom forKey:kCATransactionCompletionBlock]; [CATransaction commit];}

11年7月12日星期二

CAMediaTimingFuncation

• timing curve

• + functionWithName:

• + functionWithControlPoints::::

1.0

1.0t

x(t)

11年7月12日星期二

11年7月12日星期二

CAMediaTiming Protocol

11年7月12日星期二

CATransition

• The CATransition class implements transition animations for a layer. You can specify the transition effect from a set of predefined transitions or (on Mac OS X) by providing a custom CIFilter(optional Core Image filter object) instance.

11年7月12日星期二

CATransition-(void)performTransition{ //from ViewTransitions sample project // First create a CATransition object to describe the transition CATransition *transition = [CATransition animation]; // Animate over 3/4 of a second transition.duration = 0.75; // using the ease in/out timing function

transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; // Now to set the type of transition. Since we need to choose at random, we'll setup a couple of arrays to help us.

NSString *types[4] = {kCATransitionMoveIn, kCATransitionPush, kCATransitionReveal, kCATransitionFade}; NSString *subtypes[4] = {kCATransitionFromLeft, kCATransitionFromRight, kCATransitionFromTop, kCATransitionFromBottom}; int rnd = random() % 4; transition.type = types[rnd]; if(rnd < 3) // if we didn't pick the fade transition, then we need to set a subtype too { transition.subtype = subtypes[random() % 4]; } // Finally, to avoid overlapping transitions we assign ourselves as the delegate for the animation and wait for the // -animationDidStop:finished: message. When it comes in, we will flag that we are no longer transitioning. transitioning = YES; transition.delegate = self; // Next add it to the containerView's layer. This will perform the transition based on how we change its contents.

[containerView.layer addAnimation:transition forKey:nil]; // Here we hide view1, and show view2, which will cause Core Animation to animate view1 away and view2 in. view1.hidden = YES; view2.hidden = NO; // And so that we will continue to swap between our two images, we swap the instance variables referencing them. UIImageView *tmp = view2; view2 = view1; view1 = tmp;}

11年7月12日星期二

UI

UIWindowUIScreen

UIResponder

UIViewController

UIView

CALayer

contents

UIImageView

UIImage(Draw)

CGImageRef(Draw)

帧动画

UIEvent

Draw

CGContext

UIImage,NSString

11年7月12日星期二

UI

UIResponder

UIViewController

UIView

CALayer

contents

UIImageView

UIImage(Draw)

CGImageRef(Draw)CGImageCreateWithImageInRect

stretchableImageWithLeftCapWidth:topCapHeight:

分割

帧动画

UIEvent

UIGraphicsBeginImageContext

缩放/倒影

指定位置拉伸

Draw

CGContext

UIImage,NSString

11年7月12日星期二

CALayer

•层像是铺在⼀一个内容固定对象上的⼀一个片• Layer Properties ( Animatable 26个)

11年7月12日星期二

大小和位置CGRect teamLogoFrame = CGRectMake(150.0, 100.0, 50.0, 75.0);teamLogoView.layer.frame = teamLogoFrame;

管理和显示要在⼀一个特殊的索引里面插入层,可以使用atIndex 参数。

[ gameLayer insertSublayer: HUDView.layer atIndex: 1 ];

要在另⼀一个层的上面或者下面插入层,可以使用above 或者 below 参数

[ gameLayer insertSublayer: HUDView.layer below: backgroundView.layer ];[ gameLayer insertSublayer: HUDView.layer above: characterView.layer ];

渲染[ gameLayer setNeedsDisplay ];

圆角layer.cornerRadius = 3;layer.masksToBounds = YES;

11年7月12日星期二

3D或仿射变换

characterView.layer.transform = CATransform3DMakeScale(-1.0, -1.0, 1.0);

CGAffineTransform transform = CGAffineTransformMakeRotation(45.0);backgroundView.layer.affineTransform = transform;

CGAffineTransform 不是Layer属性,但是可以和CATransform3D转换变形iPhone的支持缩放,旋转,仿射,翻转(translation)的转变CATransform3D myTransform;myTransform = CATransform3DMakeRotation(angle, x, y, z);double radians(float degrees) { return ( degrees * 3.14159265 ) / 180.0;}当你创建⼀一个转换的时候,你将要调用这个方法:myTransform = CATransform3DMakeRotation(radians(45.0), 0.0, 1.0, 0.0);层将执行分配给transform属性的转换:imageView.layer.transform = myTransform;

11年7月12日星期二

Implicit Animation// assume that the layer is current positioned at (100.0,100.0)

theLayer.position=CGPointMake(500.0,500.0);

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

 Implicitly animating multiple properties of multiple layers

11年7月12日星期二

Explicit Animation 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"];

addAnimation:forKey:removeAnimationForKey:removeAllAnimations

Starting and Stopping Explicit Animations

11年7月12日星期二

11年7月12日星期二

11年7月12日星期二

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 // the key path is relative to the target animation object (in this case a CALayer) theAnimation=[CAKeyframeAnimation animationWithKeyPath:@"position"]; theAnimation.path=thePath; // set the duration to 5.0 seconds theAnimation.duration=5.0; // release the path CGPathRelease(thePath);

11年7月12日星期二

CALayer *welcomeLayer = placardView.layer; // Create a keyframe animation to follow a path back to the center CAKeyframeAnimation *bounceAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; bounceAnimation.removedOnCompletion = NO; CGFloat animationDuration = 1.5; // Create the path for the bounces CGMutablePathRef thePath = CGPathCreateMutable(); CGFloat midX = self.center.x; CGFloat midY = self.center.y; CGFloat originalOffsetX = placardView.center.x - midX; CGFloat originalOffsetY = placardView.center.y - midY; CGFloat offsetDivider = 4.0; BOOL stopBouncing = NO; // Start the path at the placard's current location CGPathMoveToPoint(thePath, NULL, placardView.center.x, placardView.center.y); CGPathAddLineToPoint(thePath, NULL, midX, midY); // Add to the bounce path in decreasing excursions from the center while (stopBouncing != YES) { CGPathAddLineToPoint(thePath, NULL, midX + originalOffsetX/offsetDivider, midY + originalOffsetY/offsetDivider); CGPathAddLineToPoint(thePath, NULL, midX, midY);

............... } bounceAnimation.path = thePath; bounceAnimation.duration = animationDuration; // Create a basic animation to restore the size of the placard CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath:@"transform"]; transformAnimation.removedOnCompletion = YES; transformAnimation.duration = animationDuration; transformAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DIdentity]; // Create an animation group to combine the keyframe and basic animations CAAnimationGroup *theGroup = [CAAnimationGroup animation]; // Set self as the delegate to allow for a callback to reenable user interaction theGroup.delegate = self; theGroup.duration = animationDuration; theGroup.timingFunction = [[CAMediaTimingFunction alloc] initWithControlPoints:0.5 :1.0 :0.5 :0]; theGroup.animations = [NSArray arrayWithObjects:bounceAnimation, transformAnimation, nil]; // Add the animation group to the layer [welcomeLayer addAnimation:theGroup forKey:@"animatePlacardViewToCenter"]; // Set the placard view's center and transformation to the original values in preparation for the end of the animation placardView.center = self.center; placardView.transform = CGAffineTransformIdentity;}

11年7月12日星期二

Demo

11年7月12日星期二

- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag { NSLog(@"[MainView]%@",[theAnimation valueForKey:@"name"]); if(flag && [[theAnimation valueForKey:@"name"] isEqual:@"animation"]){ [self test]; }else{ //[[NSNotificationCenter defaultCenter] postNotificationName:@"TailAnimationDidStop" object:self]; return; }}

[theGroup setValue:name forKey:@"name"];

设置回调方法

11年7月12日星期二

-(void) addTextLayersTo:(CALayer*) layer{ // If necessary, create container for the text layers if(!letters) { letters = [[NSMutableArray alloc] initWithCapacity:1]; } CALayer* letter; for(letter in letters) { [letter removeFromSuperlayer]; } [letters removeAllObjects]; CGFontRef font = CGFontCreateWithFontName(CFSTR("Courier")); NSString* text = @"The quick brown fox"; CGFloat fontSize = 28; // We are using a mono-spaced font, so CGFloat textWidth = [text length]*fontSize; // We want to center the text CGFloat xStart= CGRectGetMidX(layer.bounds)-textWidth/2.0; NSUInteger i; for(i=0;i<1;++i) { CGPoint pos = CGPointMake(xStart,CGRectGetMaxY(layer.bounds)-50); NSUInteger k; for(k=0;k<text.length;++k) { CATextLayer* letter = [[CATextLayer alloc] init]; [letters addObject:letter];

letter.foregroundColor = [UIColor blueColor].CGColor; letter.bounds = CGRectMake(0, 0, fontSize, fontSize); letter.position = pos; letter.font = font; letter.fontSize = fontSize; letter.string = [text substringWithRange:NSMakeRange(k, 1)]; [layer addSublayer:letter]; [letter release]; pos.x+=fontSize; } } CGFontRelease(font); topOfString = CGRectGetMaxY(layer.bounds)-50;}

CATextLayer Create

11年7月12日星期二

参考资源Core Animation Cookbook

Core Animation Programming Guide

Core Animation

Programming With Quartz 2D

11年7月12日星期二

参考资源Core Animation Cookbook

Core Animation Programming Guide

Core Animation

Programming With Quartz 2D

11年7月12日星期二

参考资源Core Animation Cookbook

Core Animation Programming Guide

Core Animation

Programming With Quartz 2D

11年7月12日星期二

参考资源Core Animation Cookbook

Core Animation Programming Guide

Core Animation

Programming With Quartz 2D

11年7月12日星期二

参考资源Core Animation Cookbook

Core Animation Programming Guide

Core Animation

Programming With Quartz 2D

11年7月12日星期二

WWDC11 Session 421 WWDC10 Session 123 ,Session 424, Session 425 WWDC09 Session 132, Session 303 WWDC08 Session 711, Session 716

11年7月12日星期二

谢谢!

11年7月12日星期二