一、簡單介紹
CAPropertyAnimation的子類
屬性解析:
fromValue:keyPath相應屬性的初始值
toValue:keyPath相應屬性的結束值
隨著動畫的進行,在長度為duration的持續時間內,keyPath相應屬性的值從fromValue漸漸地變為toValue
如果fillMode=kCAFillModeForwards和removedOnComletion=NO,那麼在動畫執行完畢後,圖層會保持顯示動畫執行後的狀態。但在實質上,圖層的屬性值還是動畫執行前的初始值,並沒有真正被改變。
比如,CALayer的position初始值為(0,0),CABasicAnimation的fromValue為(10,10),toValue為(100,100),雖然動畫執行完畢後圖層保持在(100,100)這個位置,實質上圖層的position還是為(0,0)
二、平移動畫
代碼示例:
代碼如下:
//
// YYViewController.m
// 07-核心動畫(基礎動畫)
//
// Created by apple on 14-6-21.
// Copyright (c) 2014年 itcase. All rights reserved.
//
#import "YYViewController.h"
@interface YYViewController ()
@property(nonatomic,strong)CALayer *myLayer;
@end
代碼如下:
@implementation YYViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//創建layer
CALayer *myLayer=[CALayer layer];
//設置layer的屬性
myLayer.bounds=CGRectMake(0, 0, 50, 80);
myLayer.backgroundColor=[UIColor yellowColor].CGColor;
myLayer.position=CGPointMake(50, 50);
myLayer.anchorPoint=CGPointMake(0, 0);
myLayer.cornerRadius=20;
//添加layer
[self.view.layer addSublayer:myLayer];
self.myLayer=myLayer;
}
//設置動畫(基礎動畫)
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//1.創建核心動畫
// CABasicAnimation *anima=[CABasicAnimation animationWithKeyPath:<#(NSString *)#>]
CABasicAnimation *anima=[CABasicAnimation animation];
//1.1告訴系統要執行什麼樣的動畫
anima.keyPath=@"position";
//設置通過動畫,將layer從哪兒移動到哪兒
anima.fromValue=[NSValue valueWithCGPoint:CGPointMake(0, 0)];
anima.toValue=[NSValue valueWithCGPoint:CGPointMake(200, 300)];
//1.2設置動畫執行完畢之後不刪除動畫
anima.removedOnCompletion=NO;
//1.3設置保存動畫的最新狀態
anima.fillMode=kCAFillModeForwards;
//2.添加核心動畫到layer
[self.myLayer addAnimation:anima forKey:nil];
}
@end
代碼說明:
第42行設置的keyPath是@"position",說明要修改的是CALayer的position屬性,也就是會執行平移動畫
第44,45行,這裡的屬性接收的時id類型的參數,因此並不能直接使用CGPoint這種結構體類型,而是要先包裝成NSValue對象後再使用。
默認情況下,動畫執行完畢後,動畫會自動從CALayer上移除,CALayer又會回到原來的狀態。為了保持動畫執行後的狀態,可以加入第48,50行代碼
byValue和toValue的區別,前者是在當前的位置上增加多少,後者是到指定的位置。
執行效果:
設置代理:設置動畫的代理,可以監聽動畫的執行過程,這裡設置控制器為代理。
代碼示例:
代碼如下:
#import "YYViewController.h"
@interface YYViewController ()
@property(nonatomic,strong)CALayer *myLayer;
@end
@implementation YYViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//創建layer
CALayer *myLayer=[CALayer layer];
//設置layer的屬性
myLayer.bounds=CGRectMake(0, 0, 50, 80);
myLayer.backgroundColor=[UIColor yellowColor].CGColor;
myLayer.position=CGPointMake(50, 50);
myLayer.anchorPoint=CGPointMake(0, 0);
myLayer.cornerRadius=20;
//添加layer
[self.view.layer addSublayer:myLayer];
self.myLayer=myLayer;
}
//設置動畫(基礎動畫)
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//1.創建核心動畫
// CABasicAnimation *anima=[CABasicAnimation animationWithKeyPath:<#(NSString *)#>]
CABasicAnimation *anima=[CABasicAnimation animation];
//1.1告訴系統要執行什麼樣的動畫
anima.keyPath=@"position";
//設置通過動畫,將layer從哪兒移動到哪兒
anima.fromValue=[NSValue valueWithCGPoint:CGPointMake(0, 0)];
anima.toValue=[NSValue valueWithCGPoint:CGPointMake(200, 300)];
//1.2設置動畫執行完畢之後不刪除動畫
anima.removedOnCompletion=NO;
//1.3設置保存動畫的最新狀態
anima.fillMode=kCAFillModeForwards;
anima.delegate=self;
//打印
NSString *str=NSStringFromCGPoint(self.myLayer.position);
NSLog(@"執行前:%@",str);
//2.添加核心動畫到layer
[self.myLayer addAnimation:anima forKey:nil];
}
-(void)animationDidStart:(CAAnimation *)anim
{
NSLog(@"開始執行動畫");
}
-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
//動畫執行完畢,打印執行完畢後的position值
NSString *str=NSStringFromCGPoint(self.myLayer.position);
NSLog(@"執行後:%@",str);
}
@end
打印position的屬性值,驗證圖層的屬性值還是動畫執行前的初始值{50,50},並沒有真正被改變為{200,300}。
三、縮放動畫
實現縮放動畫的代碼示例:
代碼如下:
//
// YYViewController.m
// 08-核心動畫平移
//
// Created by apple on 14-6-21.
// Copyright (c) 2014年 itcase. All rights reserved.
//
#import "YYViewController.h"
@interface YYViewController ()
@property(nonatomic,strong)CALayer *myLayer;
@end
代碼如下:
@implementation YYViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//創建layer
CALayer *myLayer=[CALayer layer];
//設置layer的屬性
myLayer.bounds=CGRectMake(0, 0, 150, 60);
myLayer.backgroundColor=[UIColor yellowColor].CGColor;
myLayer.position=CGPointMake(50, 50);
myLayer.anchorPoint=CGPointMake(0, 0);
myLayer.cornerRadius=40;
//添加layer
[self.view.layer addSublayer:myLayer];
self.myLayer=myLayer;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//1.創建動畫
CABasicAnimation *anima=[CABasicAnimation animationWithKeyPath:@"bounds"];
//1.1設置動畫執行時間
anima.duration=2.0;
//1.2設置動畫執行完畢後不刪除動畫
anima.removedOnCompletion=NO;
//1.3設置保存動畫的最新狀態
anima.fillMode=kCAFillModeForwards;
//1.4修改屬性,執行動畫
anima.toValue=[NSValue valueWithCGRect:CGRectMake(0, 0, 200, 200)];
//2.添加動畫到layer
[self.myLayer addAnimation:anima forKey:nil];
}
@end
實現效果:
四、旋轉動畫
代碼示例:
代碼如下:
//
// YYViewController.m
// 09-核心動畫旋轉
//
// Created by apple on 14-6-21.
// Copyright (c) 2014年 itcase. All rights reserved.
//
#import "YYViewController.h"
@interface YYViewController ()
@property(nonatomic,strong)CALayer *myLayer;
@end
代碼如下:
@implementation YYViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//創建layer
CALayer *myLayer=[CALayer layer];
//設置layer的屬性
myLayer.bounds=CGRectMake(0, 0, 150, 60);
myLayer.backgroundColor=[UIColor yellowColor].CGColor;
myLayer.position=CGPointMake(50, 50);
myLayer.anchorPoint=CGPointMake(0, 0);
myLayer.cornerRadius=40;
//添加layer
[self.view.layer addSublayer:myLayer];
self.myLayer=myLayer;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//1.創建動畫
CABasicAnimation *anima=[CABasicAnimation animationWithKeyPath:@"transform"];
//1.1設置動畫執行時間
anima.duration=2.0;
//1.2修改屬性,執行動畫
anima.toValue=[NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI_2+M_PI_4, 1, 1, 0)];
//1.3設置動畫執行完畢後不刪除動畫
anima.removedOnCompletion=NO;
//1.4設置保存動畫的最新狀態
anima.fillMode=kCAFillModeForwards;
//2.添加動畫到layer
[self.myLayer addAnimation:anima forKey:nil];
}
@end
實現效果:
補充:
可以通過transform(KVC)的方式來進行設置。
代碼示例(平移):
代碼如下:
#import "YYViewController.h"
@interface YYViewController ()
@property(nonatomic,strong)CALayer *myLayer;
@end
代碼如下:
@implementation YYViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//創建layer
CALayer *myLayer=[CALayer layer];
//設置layer的屬性
myLayer.bounds=CGRectMake(0, 0, 150, 60);
myLayer.backgroundColor=[UIColor yellowColor].CGColor;
myLayer.position=CGPointMake(50, 50);
myLayer.anchorPoint=CGPointMake(0, 0);
myLayer.cornerRadius=40;
//添加layer
[self.view.layer addSublayer:myLayer];
self.myLayer=myLayer;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//1.創建動畫
CABasicAnimation *anima=[CABasicAnimation animation];
anima.keyPath=@"transform";
//1.1設置動畫執行時間
anima.duration=2.0;
//1.2修改屬性,執行動畫
anima.toValue=[NSValue valueWithCATransform3D:CATransform3DMakeTranslation(0, 100, 1)];
//1.3設置動畫執行完畢後不刪除動畫
anima.removedOnCompletion=NO;
//1.4設置保存動畫的最新狀態
anima.fillMode=kCAFillModeForwards;
//2.添加動畫到layer
[self.myLayer addAnimation:anima forKey:nil];
}
實現效果:
繪制的圖形在y的方向上移動100個單位。
五、關鍵幀動畫
1.簡單介紹
是CApropertyAnimation的子類,跟CABasicAnimation的區別是:CABasicAnimation只能從一個數值(fromValue)變到另一個數值(toValue),而CAKeyframeAnimation會使用一個NSArray保存這些數值
屬性解析:
values:就是上述的NSArray對象。裡面的元素稱為”關鍵幀”(keyframe)。動畫對象會在指定的時間(duration)內,依次顯示values數組中的每一個關鍵幀
path:可以設置一個CGPathRef\CGMutablePathRef,讓層跟著路徑移動。path只對CALayer的anchorPoint和position起作用。如果你設置了path,那麼values將被忽略
keyTimes:可以為對應的關鍵幀指定對應的時間點,其取值范圍為0到1.0,keyTimes中的每一個時間值都對應values中的每一幀.當keyTimes沒有設置的時候,各個關鍵幀的時間是平分的
說明:CABasicAnimation可看做是最多只有2個關鍵幀的CAKeyframeAnimation
2.代碼示例
第一種方式:
代碼:
代碼如下:
//
// YYViewController.m
// 10-核心動畫(關鍵幀動畫1)
//
// Created by apple on 14-6-21.
// Copyright (c) 2014年 itcase. All rights reserved.
//
#import "YYViewController.h"
@interface YYViewController ()
@property (weak, nonatomic) IBOutlet UIView *customView;
@end
代碼如下:
@implementation YYViewController
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//1.創建核心動畫
CAKeyframeAnimation *keyAnima=[CAKeyframeAnimation animation];
//平移
keyAnima.keyPath=@"position";
//1.1告訴系統要執行什麼動畫
NSValue *value1=[NSValue valueWithCGPoint:CGPointMake(100, 100)];
NSValue *value2=[NSValue valueWithCGPoint:CGPointMake(200, 100)];
NSValue *value3=[NSValue valueWithCGPoint:CGPointMake(200, 200)];
NSValue *value4=[NSValue valueWithCGPoint:CGPointMake(100, 200)];
NSValue *value5=[NSValue valueWithCGPoint:CGPointMake(100, 100)];
keyAnima.values=@[value1,value2,value3,value4,value5];
//1.2設置動畫執行完畢後,不刪除動畫
keyAnima.removedOnCompletion=NO;
//1.3設置保存動畫的最新狀態
keyAnima.fillMode=kCAFillModeForwards;
//1.4設置動畫執行的時間
keyAnima.duration=4.0;
//1.5設置動畫的節奏
keyAnima.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
//設置代理,開始—結束
keyAnima.delegate=self;
//2.添加核心動畫
[self.customView.layer addAnimation:keyAnima forKey:nil];
}
-(void)animationDidStart:(CAAnimation *)anim
{
NSLog(@"開始動畫");
}
-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
NSLog(@"結束動畫");
}
@end
說明:這個項目在storyboard中拖入了一個view,並和控制器中的custom進行了關聯。
效果和打印結果:
補充:設置動畫的節奏
第二種方式(使用path)讓layer在指定的路徑上移動(畫圓):
代碼:
代碼如下:
#import "YYViewController.h"
@interface YYViewController ()
@property (weak, nonatomic) IBOutlet UIView *customView;
@end
代碼如下:
@implementation YYViewController
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//1.創建核心動畫
CAKeyframeAnimation *keyAnima=[CAKeyframeAnimation animation];
//平移
keyAnima.keyPath=@"position";
//1.1告訴系統要執行什麼動畫
//創建一條路徑
CGMutablePathRef path=CGPathCreateMutable();
//設置一個圓的路徑
CGPathAddEllipseInRect(path, NULL, CGRectMake(150, 100, 100, 100));
keyAnima.path=path;
//有create就一定要有release
CGPathRelease(path);
//1.2設置動畫執行完畢後,不刪除動畫
keyAnima.removedOnCompletion=NO;
//1.3設置保存動畫的最新狀態
keyAnima.fillMode=kCAFillModeForwards;
//1.4設置動畫執行的時間
keyAnima.duration=5.0;
//1.5設置動畫的節奏
keyAnima.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
//設置代理,開始—結束
keyAnima.delegate=self;
//2.添加核心動畫
[self.customView.layer addAnimation:keyAnima forKey:nil];
}
-(void)animationDidStart:(CAAnimation *)anim
{
NSLog(@"開始動畫");
}
-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
NSLog(@"結束動畫");
}
@end
說明:可以通過path屬性,讓layer在指定的軌跡上運動。
停止動畫:
代碼如下:
#import "YYViewController.h"
@interface YYViewController ()
@property (weak, nonatomic) IBOutlet UIView *customView;
- (IBAction)stopOnClick:(UIButton *)sender;
@end
代碼如下:
@implementation YYViewController
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//1.創建核心動畫
CAKeyframeAnimation *keyAnima=[CAKeyframeAnimation animation];
//平移
keyAnima.keyPath=@"position";
//1.1告訴系統要執行什麼動畫
//創建一條路徑
CGMutablePathRef path=CGPathCreateMutable();
//設置一個圓的路徑
CGPathAddEllipseInRect(path, NULL, CGRectMake(150, 100, 100, 100));
keyAnima.path=path;
//有create就一定要有release
CGPathRelease(path);
//1.2設置動畫執行完畢後,不刪除動畫
keyAnima.removedOnCompletion=NO;
//1.3設置保存動畫的最新狀態
keyAnima.fillMode=kCAFillModeForwards;
//1.4設置動畫執行的時間
keyAnima.duration=5.0;
//1.5設置動畫的節奏
keyAnima.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
//2.添加核心動畫
[self.customView.layer addAnimation:keyAnima forKey:@"wendingding"];
}
- (IBAction)stopOnClick:(UIButton *)sender {
//停止self.customView.layer上名稱標示為wendingding的動畫
[self.customView.layer removeAnimationForKey:@"wendingding"];
}
@end
點擊停止動畫,程序內部會調用 [self.customView.layer removeAnimationForKey:@"wendingding"];停止self.customView.layer上名稱標示為wendingding的動畫。
3.圖標抖動
代碼示例:
代碼如下:
//
// YYViewController.m
// 12-圖標抖動
//
// Created by apple on 14-6-21.
// Copyright (c) 2014年 itcase. All rights reserved.
//
#import "YYViewController.h"
#define angle2Radian(angle) ((angle)/180.0*M_PI)
@interface YYViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *iconView;
@end
代碼如下:
@implementation YYViewController
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//1.創建核心動畫
CAKeyframeAnimation *keyAnima=[CAKeyframeAnimation animation];
keyAnima.keyPath=@"transform.rotation";
//設置動畫時間
keyAnima.duration=0.1;
//設置圖標抖動弧度
//把度數轉換為弧度 度數/180*M_PI
keyAnima.values=@[@(-angle2Radian(4)),@(angle2Radian(4)),@(-angle2Radian(4))];
//設置動畫的重復次數(設置為最大值)
keyAnima.repeatCount=MAXFLOAT;
keyAnima.fillMode=kCAFillModeForwards;
keyAnima.removedOnCompletion=NO;
//2.添加動畫
[self.iconView.layer addAnimation:keyAnima forKey:nil];
}
@end
說明:圖標向左向右偏轉一個弧度(4),產生抖動的視覺效果。
程序界面: