layer是動(dòng)畫的核心
1 通過自定義layer繪制簡單線條
MYLayer繼承自CALayer
#import "MYLayer.h"
@implementation MYLayer
-(void)drawInContext:(CGContextRef)ctx{
CGMutablePathRef thePath = CGPathCreateMutable();
CGPathMoveToPoint(thePath,NULL,20.0f,100.f);
CGPathAddCurveToPoint(thePath,
NULL,
15.f,250.0f,
295.0f,250.0f,
295.0f,450.0f);
CGContextBeginPath(ctx);
CGContextAddPath(ctx, thePath);
CGContextSetLineWidth(ctx, 5);
CGContextStrokePath(ctx);
// Release the path
CFRelease(thePath);
}
@end
2 UIImageView設(shè)置圖片過小時(shí)太模糊
就算設(shè)置了imageView.contentMode = UIViewContentModeScaleAspectFit;也不行,解決方案為設(shè)置下imageView的layer的contentsGravity屬性為kCAGravityCenter即可。
截取contentsGravity的定義:

3 CABasicAnimation最基礎(chǔ)的動(dòng)畫
設(shè)置好屬性后直接應(yīng)用在layer上
CABasicAnimation *fade = [CABasicAnimation animationWithKeyPath:@"shadowOpacity"];
fade.fromValue = [NSNumber numberWithFloat:1.0];
fade.toValue = [NSNumber numberWithFloat:0.0];
fade.duration = 2.0f;
[layer addAnimation:fade forKey:@"shadowOpacity"];
注意動(dòng)畫只是模擬一個(gè)假的過程,layer的shadowOpacity其實(shí)是沒有改變的 ,所以如果真的需要改變屬性的值,記得在動(dòng)畫完畢后設(shè)置一下:
layer.shadowOpacity = 0;
4、CAKeyframeAnimation
//創(chuàng)建一個(gè)路徑
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, 0, 64);
CGPathAddCurveToPoint(path, NULL, SCREEN_WIDTH -20, 100, 20, SCREEN_HEIGHT * 0.5, SCREEN_WIDTH, SCREEN_HEIGHT);
CAKeyframeAnimation *keyAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
keyAnimation.path = path;
keyAnimation.duration = 10.0f;
[layer addAnimation:keyAnimation forKey:@"position"];
5 組合動(dòng)畫
//改borderWidth
CAKeyframeAnimation *widthAnim = [CAKeyframeAnimation animationWithKeyPath:@"borderWidth"];
NSArray* widthValues = [NSArray arrayWithObjects:@10.0, @5.0, @1.0,@10.0, @5.0, @1.0,@10.0, @5.0, @1.0, nil];
widthAnim.values = widthValues;
widthAnim.calculationMode = kCAAnimationPaced;
//改borderColor
CAKeyframeAnimation *colorAnim = [CAKeyframeAnimation animationWithKeyPath:@"borderColor"];
NSArray *colorValues = [NSArray arrayWithObjects:(id)[UIColor redColor].CGColor,(id)[UIColor greenColor].CGColor,(id)[UIColor orangeColor].CGColor, nil];
colorAnim.values = colorValues;
colorAnim.calculationMode = kCAAnimationPaced;
CAAnimationGroup *group = [[CAAnimationGroup alloc] init];
group.animations = @[widthAnim,colorAnim];
group.duration = 2.0f;
[imageView.layer addAnimation:group forKey:@"borderChanged"];
效果就是一邊改border寬度,一邊變換顏色

6 UIView動(dòng)畫和CA動(dòng)畫一起使用
原文: As a result, changes you make to the layer are automatically reflected by the view object as well. This behavior means that you can use either the Core Animation or UIView interfaces to make your changes.
[UIView animateWithDuration:1.0 animations:^{
// Change the opacity implicitly.
imageView.layer.opacity = 0.1;
// Change the position explicitly.
CABasicAnimation* theAnim = [CABasicAnimation animationWithKeyPath:@"position"];
theAnim.fromValue = [NSValue valueWithCGPoint:imageView.layer.position];
theAnim.toValue = [NSValue valueWithCGPoint:CGPointMake(0, SCREEN_HEIGHT)];
theAnim.duration = 3.0;
[imageView.layer addAnimation:theAnim forKey:@"AnimateFrame"];
}];
7 CATransition動(dòng)畫
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;
效果:

8動(dòng)畫暫停與恢復(fù)
//暫停
-(void)pauseAnim{
CFTimeInterval pauseTime = [imageView.layer convertTime:CACurrentMediaTime() toLayer:nil];
imageView.layer.speed = 0.0;
imageView.layer.timeOffset = pauseTime;
}
//恢復(fù)
-(void)resumeAnim{
CFTimeInterval pausedTime = [imageView.layer timeOffset];
imageView.layer.speed = 1.0;
imageView.layer.timeOffset = 0;
imageView.layer.beginTime = 0;
CFTimeInterval timeSincePause = [imageView.layer convertTime:CACurrentMediaTime() toLayer:nil] - pausedTime;
imageView.layer.beginTime = timeSincePause;
}
timeOffset的作用:
比如有個(gè)動(dòng)畫整個(gè)過程需要三秒,如果設(shè)置該動(dòng)畫的timeOffset為一秒,那么這個(gè)動(dòng)畫為從原先設(shè)計(jì)好的流程中的第一秒結(jié)束的位置直接開始執(zhí)行,這樣2秒后其實(shí)就走完了,但是記住timeOffset只會影響動(dòng)畫的執(zhí)行開始位置,動(dòng)畫的整個(gè)過程還是要執(zhí)行的,所以接著動(dòng)畫會執(zhí)行開頭錯(cuò)過的那第一秒的動(dòng)畫。
所以以上的流程就是:
1.首先獲取到點(diǎn)擊暫停是的layer運(yùn)行時(shí)間,取這段時(shí)間出來然后儲存在timeOffset中。
2.恢復(fù)動(dòng)畫時(shí),首先獲取到當(dāng)前l(fā)ayer的timeOffset,也就是之前走了多少了,然后用獲取到的當(dāng)前時(shí)間減去timeOffset,就是應(yīng)該從其實(shí)位置偏移多少,從這開始執(zhí)行就可以了beginTime(個(gè)人理解,如果有誤請?zhí)岢觯?
效果:
