前言:iOS與MacOS的坐標(biāo)系不同,iOS使用的是左手坐標(biāo)系慌申,坐標(biāo)原點(diǎn)是在左上角,MacOS 使用的是右手坐標(biāo)系,原點(diǎn)是在左下角蹄溉。
簡單的動(dòng)畫實(shí)現(xiàn):矩形平移動(dòng)畫
- (void)viewDidLoad {
[super viewDidLoad];
//1.創(chuàng)建一個(gè)layer
CALayer *mylayer = [CALayer layer];
//2.設(shè)置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;
//3.添加layer
[self.view.layer addSublayer:mylayer];
self.mylayer = mylayer;
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
//1.創(chuàng)建核心動(dòng)畫(劇本)
CABasicAnimation *anima = [CABasicAnimation animation];
// 設(shè)置劇本具體動(dòng)畫內(nèi)容
// 設(shè)置layer的position屬性咨油,即平移
anima.keyPath = @"position";
anima.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, 0)];
anima.toValue = [NSValue valueWithCGPoint:CGPointMake(200, 300)];
// 設(shè)置動(dòng)畫執(zhí)行完畢之后不刪除動(dòng)畫
anima.removedOnCompletion = NO;
// 設(shè)置保存動(dòng)畫的最新狀態(tài)
anima.fillMode = kCAFillModeForwards;
//2.添加核心動(dòng)畫到layer(執(zhí)行劇本)
[self.mylayer addAnimation:anima forKey:nil];
}
這里有一個(gè)重要的知識(shí)點(diǎn):position和anchorPoint,不懂的可以瀏覽這篇博客大頭青年柒爵,瞬間秒懂役电。這里就簡單講講我的理解:一個(gè)layer的位置frame是由position和anchorPoint共同決定的(不管layer之前的frame是多少都沒有影響)只要有一個(gè)改變了,那么layer的位置就會(huì)改變棉胀。第二了就是position和anchorPoint是不同坐標(biāo)系的重合點(diǎn)法瑟,即指同一個(gè)點(diǎn)。
監(jiān)聽動(dòng)畫的執(zhí)行過程唁奢,設(shè)置代理
在上方代碼的基礎(chǔ)上添加代理
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
//1.創(chuàng)建核心動(dòng)畫(劇本)
CABasicAnimation *anima = [CABasicAnimation animation];
// 設(shè)置劇本具體動(dòng)畫內(nèi)容
// 設(shè)置layer的position屬性霎挟,即平移
anima.keyPath = @"position";
anima.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, 0)];
anima.toValue = [NSValue valueWithCGPoint:CGPointMake(200, 300)];
// 設(shè)置動(dòng)畫執(zhí)行完畢之后不刪除動(dòng)畫
anima.removedOnCompletion = NO;
// 設(shè)置保存動(dòng)畫的最新狀態(tài)
anima.fillMode = kCAFillModeForwards;
// 設(shè)置代理
anima.delegate = self;
NSString *str = NSStringFromCGPoint(self.myLayer.position);
NSLog(@"執(zhí)行前:%@",str);
//2.添加核心動(dòng)畫到layer(執(zhí)行劇本)
[self.mylayer addAnimation:anima forKey:nil];
}
- (void)animationDidStart:(CAAnimation*)anim{
NSLog(@"開始執(zhí)行動(dòng)畫");
}
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
NSString *str = NSStringFromCGPoint(self.myLayer.position);
NSLog(@"執(zhí)行后:%@",str);
}
/*
輸出結(jié)果:
**2016-12-01 23:50:47.172 CAPropertyAnimationDemo[2829:99758] ****動(dòng)畫執(zhí)行前:****{50, 50}**
**2016-12-01 23:50:47.173 CAPropertyAnimationDemo[2829:99758] ****動(dòng)畫開始執(zhí)行了**
**2016-12-01 23:50:47.423 CAPropertyAnimationDemo[2829:99758] ****動(dòng)畫執(zhí)行后:****{50, 50}**
*/
從上面的例子得出:即使保持了圖層在執(zhí)行完動(dòng)畫后的狀態(tài)麻掸,但是實(shí)質(zhì)上圖層的屬性值還是動(dòng)畫執(zhí)行前的初始值酥夭,并沒有真正被改動(dòng)。如上例中的position
CABasicAnimation 還有一組重要的屬性:autoreverses 和 repeatCount 脊奋。autoreverses 是否自動(dòng)逆向執(zhí)行動(dòng)畫到原先狀態(tài)熬北,執(zhí)行時(shí)間與正向動(dòng)畫持續(xù)時(shí)間一致。repeatCount 是否重復(fù)動(dòng)畫狂魔。這兩個(gè)屬性默認(rèn)值是NO蒜埋。
平移、縮放最楷、旋轉(zhuǎn)
#import "ViewController.h"
@interface ViewController ()<CAAnimationDelegate>
@property (nonatomic,strong) CALayer *mylayer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//1.創(chuàng)建一個(gè)layer
CALayer *mylayer = [CALayer layer];
//2.設(shè)置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;
//3.添加layer
[self.view.layer addSublayer:mylayer];
self.mylayer = mylayer;
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
// [self keyPathWithPositionAnimation];
// [self keyPathWithBoundsAnimation];
// [self keyPathWithTransformAnimation];
[self positionByTransformAnimation];
}
#pragma mark - 平移動(dòng)畫
- (void)keyPathWithPositionAnimation{
//1.創(chuàng)建核心動(dòng)畫(劇本)
CABasicAnimation *anima = [CABasicAnimation animation];
// 設(shè)置劇本具體動(dòng)畫內(nèi)容
// 設(shè)置layer的position屬性整份,即平移
// 注意:如果沒有設(shè)置起始位置"fromValue"的值,那么會(huì)從當(dāng)前位置開始
anima.keyPath = @"position";
anima.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, 0)];
anima.toValue = [NSValue valueWithCGPoint:CGPointMake(200, 300)];
anima.duration = 2;
// 設(shè)置動(dòng)畫執(zhí)行完畢之后不刪除動(dòng)畫
anima.removedOnCompletion = NO;
// 設(shè)置保存動(dòng)畫的最新狀態(tài)
anima.fillMode = kCAFillModeForwards;
anima.delegate = self;
NSString *string = NSStringFromCGRect(self.mylayer.frame);
NSLog(@"動(dòng)畫執(zhí)行前:%@",string);
//2.添加核心動(dòng)畫到layer(執(zhí)行劇本)
[self.mylayer addAnimation:anima forKey:nil];
}
#pragma mark - 縮放
- (void)keyPathWithBoundsAnimation{
//1.創(chuàng)建動(dòng)畫
CABasicAnimation *anima = [CABasicAnimation animation];
anima.keyPath = @"bounds";
//1.1設(shè)置動(dòng)畫執(zhí)行時(shí)間
anima.duration = 2.0;
//1.2設(shè)置保存動(dòng)畫的最新狀態(tài)
anima.removedOnCompletion = NO;
anima.fillMode = kCAFillModeForwards;
//1.3修改屬性,執(zhí)行動(dòng)畫
anima.toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, 200, 200)];
//2.0添加動(dòng)畫到layer
[self.mylayer addAnimation:anima forKey:nil];
}
#pragma mark - 旋轉(zhuǎn)
- (void)keyPathWithTransformAnimation{
CABasicAnimation *anima = [CABasicAnimation animation];
anima.keyPath = @"transform";
anima.duration = 2.0;
anima.removedOnCompletion = NO;
anima.fillMode = kCAFillModeForwards;
anima.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI_2+M_PI_4, 1, 1, 0)];
[self.mylayer addAnimation:anima forKey:nil];
}
#pragma mark - 平移的第二種方式
- (void)positionByTransformAnimation{
CABasicAnimation *anima = [CABasicAnimation animation];
anima.keyPath = @"transform";
anima.duration = 2.0;
anima.removedOnCompletion = NO;
anima.fillMode = kCAFillModeForwards;
anima.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeTranslation(0, 100, 1)];
[self.mylayer addAnimation:anima forKey:nil];
}
- (void)animationDidStart:(CAAnimation *)anim{
NSLog(@"動(dòng)畫開始執(zhí)行了");
}
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
NSString *string = NSStringFromCGRect(self.mylayer.frame);
NSLog(@"動(dòng)畫執(zhí)行后:%@",string);
}