import "ViewController.h"
import <QuartzCore/QuartzCore.h>
define View_Side 80
define Screen_Width 320
define Screen_Height 460
import "AnimationDelegate.h"
@interface ViewController ()<CAAnimationDelegate>
{
UIView *_demoView;
}
@end
@implementation ViewController
/**
- initialize the demoview.
*/
(void)initDemoView
{
_demoView = [[UIView alloc] initWithFrame:CGRectMake(20, 20, View_Side, View_Side)];
_demoView.backgroundColor = [UIColor orangeColor];
[self.view addSubview:_demoView];
}-
(void)viewDidLoad
{
[super viewDidLoad];
[self initDemoView];[self performSelector:@selector(starAnimationScale1) withObject:nil afterDelay:2.0f];
}
/*!
設(shè)定動(dòng)畫
屬性 說明
duration 動(dòng)畫的時(shí)長
repeatCount 重復(fù)的次數(shù)。不停重復(fù)設(shè)置為 HUGE_VALF
repeatDuration 設(shè)置動(dòng)畫的時(shí)間橄登。在該時(shí)間內(nèi)動(dòng)畫一直執(zhí)行嘹履,不計(jì)次數(shù)丰滑。
beginTime 指定動(dòng)畫開始的時(shí)間稍走。從開始延遲幾秒的話哗总,設(shè)置為【CACurrentMediaTime() + 秒數(shù)】 的方式
timingFunction 設(shè)置動(dòng)畫的速度變化
autoreverses 動(dòng)畫結(jié)束時(shí)是否執(zhí)行逆動(dòng)畫
fromValue 所改變屬性的起始值
toValue 所改變屬性的結(jié)束時(shí)的值
byValue 所改變屬性相同起始值的改變量
removedOnCompletion 防止動(dòng)畫結(jié)束后回到初始狀態(tài) 所以為了使動(dòng)畫結(jié)束之后layer保持結(jié)束狀態(tài)舔涎,應(yīng)將removedOnCompletion設(shè)置為NO
fillMode 防止動(dòng)畫結(jié)束后回到初始狀態(tài) 該屬性定義了你的動(dòng)畫在開始和結(jié)束時(shí)的動(dòng)作誊役。默認(rèn)值是 kCAFillModeRemoved获列。
speed speed 改變動(dòng)畫的速度 可以直接設(shè)置動(dòng)畫上的speed屬性贫母,這樣只有這個(gè)動(dòng)畫速度压昼。
speed兩點(diǎn)需注意的:
(1)如果設(shè)置動(dòng)畫時(shí)間為4s闹啦,speed設(shè)置為2蛾坯,則動(dòng)畫只需2s即可執(zhí)行完。
(2)如果同時(shí)設(shè)置了動(dòng)畫的speed和layer 的speed抑钟,則實(shí)際的speed為兩者相乘叛本。
*/
-(void)scaleopcity{
CABasicAnimation *animaiton = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
animaiton.fromValue = @(M_PI_4);
animaiton.toValue = @(M_PI);
animaiton.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animaiton.autoreverses = NO;
animaiton.repeatCount = HUGE_VALF;
animaiton.beginTime = CACurrentMediaTime() + 1;
animaiton.delegate = self;//協(xié)議
animaiton.delegate = [[AnimationDelegate alloc]init];
// 防止動(dòng)畫結(jié)束后回到初始狀態(tài)
animaiton.removedOnCompletion = NO;
animaiton.fillMode = kCAFillModeForwards;
/*!
kCAFillModeForwards kCAFillModeForwards 設(shè)置為該值知染,動(dòng)畫即使之后layer的狀態(tài)將保持在動(dòng)畫的最后一幀艺玲,而removedOnCompletion的默認(rèn)屬性
值是 YES括蝠,所以為了使動(dòng)畫結(jié)束之后layer保持結(jié)束狀態(tài),應(yīng)將removedOnCompletion設(shè)置為NO板驳。
kCAFillModeBackwards kCAFillModeBackwards 設(shè)置為該值又跛,將會(huì)立即執(zhí)行動(dòng)畫的第一幀碍拆,不論是否設(shè)置了 beginTime屬性若治。觀察發(fā)現(xiàn),設(shè)置該值感混,剛開
始視圖不見端幼,還不知道應(yīng)用在哪里。
kCAFillModeBoth kCAFillModeBoth 該值是 kCAFillModeForwards 和 kCAFillModeBackwards的組合狀態(tài)
kCAFillModeRemoved kCAFillModeRemoved 設(shè)置為該值弧满,動(dòng)畫將在設(shè)置的 beginTime 開始執(zhí)行(如沒有設(shè)置beginTime屬性婆跑,則動(dòng)畫立即執(zhí)行),動(dòng)
畫執(zhí)行完成后將會(huì)layer的改變恢復(fù)原狀庭呜。
*/
/*
kCAMediaTimingFunctionLinear 傳這個(gè)值滑进,在整個(gè)動(dòng)畫時(shí)間內(nèi)動(dòng)畫都是以一個(gè)相同的速度來改變。也就是勻速運(yùn)動(dòng)募谎。
kCAMediaTimingFunctionEaseIn 使用該值扶关,動(dòng)畫開始時(shí)會(huì)較慢,之后動(dòng)畫會(huì)加速数冬。
kCAMediaTimingFunctionEaseOut 使用該值节槐,動(dòng)畫在開始時(shí)會(huì)較快,之后動(dòng)畫速度減慢。
kCAMediaTimingFunctionEaseInEaseOut 使用該值铜异,動(dòng)畫在開始和結(jié)束時(shí)速度較慢哥倔,中間時(shí)間段內(nèi)速度較快。
kCAMediaTimingFunctionDefault
*/
//添加動(dòng)畫
[_demoView.layer addAnimation:animaiton forKey:@"Animation"];
}
//其實(shí)比較重要的是有多個(gè)動(dòng)畫的時(shí)候如何在代理方法中區(qū)分不同的動(dòng)畫
//方式一:
//如果我們添加動(dòng)畫的視圖是全局變量揍庄,可使用該方法咆蒿。
//添加動(dòng)畫時(shí),我們使用了
//動(dòng)畫開始時(shí)
- (void)animationDidStart:(CAAnimation *)anim
{
if ([anim isEqual:[_demoView.layer animationForKey:@"Animation"]]) {
NSLog(@"動(dòng)畫組執(zhí)行了");
}
}
//動(dòng)畫結(jié)束時(shí)
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
//方法中的flag參數(shù)表明了動(dòng)畫是自然結(jié)束還是被打斷,比如調(diào)用了removeAnimationForKey:方法或removeAnimationForKey方法币绩,flag為NO蜡秽,如果是正常結(jié)束,flag為YES缆镣。
NSLog(@"結(jié)束了");
}
//方式二
//添加動(dòng)畫的視圖是局部變量時(shí)芽突,可使用該方法
//添加動(dòng)畫給動(dòng)畫設(shè)置key-value對
-(void)animationCustomDidStart{
// [positionAnima setValue:@"PositionAnima" forKey:@"AnimationKey"];
// [transformAnima setValue:@"TransformAnima" forKey:@"AnimationKey"];
}
//動(dòng)畫結(jié)束時(shí)
//- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
//{
// if ([[anim valueForKey:@"AnimationKey"]isEqualToString:@"PositionAnima"]) {
// NSLog(@"位置移動(dòng)動(dòng)畫執(zhí)行結(jié)束");
// }
// else if ([[anim valueForKey:@"AnimationKey"]isEqualToString:@"TransformAnima"]){
// NSLog(@"旋轉(zhuǎn)動(dòng)畫執(zhí)行結(jié)束");
// }
//}
//y上下跳
-(void)starAnimationScale{
CABasicAnimation *positionAnima = [CABasicAnimation animationWithKeyPath:@"position.y"];
positionAnima.duration = 0.8;
positionAnima.fromValue = @(_demoView.center.y);
positionAnima.toValue = @(_demoView.center.y-30);
positionAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
positionAnima.repeatCount = HUGE_VALF;
positionAnima.repeatDuration = 2;
positionAnima.removedOnCompletion = NO;
positionAnima.fillMode = kCAFillModeForwards;
[_demoView.layer addAnimation:positionAnima forKey:@"AnimationMoveY"];
}
//centery 中心點(diǎn)旋轉(zhuǎn)
-(void)starAnimationScale1{
CABasicAnimation *positionAnima = [CABasicAnimation animationWithKeyPath:@"position.y"];
positionAnima.fromValue = @(_demoView.center.y);
positionAnima.toValue = @(_demoView.center.y-30);
positionAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
CABasicAnimation *transformAnima = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
transformAnima.fromValue = @(0);
transformAnima.toValue = @(M_PI);
transformAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
CAAnimationGroup *animaGroup = [CAAnimationGroup animation];
animaGroup.duration = 2.0f;
animaGroup.fillMode = kCAFillModeForwards;
animaGroup.removedOnCompletion = NO;
animaGroup.animations = @[positionAnima,transformAnima];
[_demoView.layer addAnimation:animaGroup forKey:@"Animation"];
}
pragma mark - 我的旋轉(zhuǎn) 順時(shí)針
-(void)startAnimation{
CABasicAnimation* rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
rotationAnimation.toValue = [NSNumber numberWithFloat: M_PI * 2.0 ];
rotationAnimation.duration = 5.0;
rotationAnimation.cumulative = YES;
rotationAnimation.repeatCount = 1000;
[_demoView.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"];
}
-(void)opacity{
// CABasicAnimation *animation = [self opacityForever_Animation:3.0];
CABasicAnimation *animation = [self scale:[NSNumber numberWithInt:1] orgin:[NSNumber numberWithInt:1] durTimes:3.3 Rep:3];
[_demoView.layer addAnimation:animation forKey:nil];
}
pragma mark =====縮放-=============
-(CABasicAnimation *)scale:(NSNumber *)Multiple orgin:(NSNumber *)orginMultiple durTimes:(float)time Rep:(float)repertTimes
{
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
animation.fromValue = Multiple;
animation.toValue = orginMultiple;
animation.autoreverses = YES;
animation.repeatCount = repertTimes;
animation.duration = time;//不設(shè)置時(shí)候的話,有一個(gè)默認(rèn)的縮放時(shí)間.
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
return animation;
}
pragma mark ====旋轉(zhuǎn)動(dòng)畫======
-(CABasicAnimation *)rotation:(float)dur degree:(float)degree direction:(int)direction repeatCount:(int)repeatCount
{
//第一個(gè)參數(shù)是旋轉(zhuǎn)角度董瞻,后面三個(gè)參數(shù)形成一個(gè)圍繞其旋轉(zhuǎn)的向量寞蚌,起點(diǎn)位置由UIView的center屬性標(biāo)識(shí)。
CATransform3D rotationTransform = CATransform3DMakeRotation(degree, 0, 0, direction);
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform"];
animation.toValue = [NSValue valueWithCATransform3D:rotationTransform];
animation.duration = dur;
animation.autoreverses = NO;
animation.cumulative = NO;
animation.fillMode = kCAFillModeForwards;
animation.repeatCount = repeatCount;
return animation;
}
pragma mark === 永久閃爍的動(dòng)畫 ======
-(CABasicAnimation *)opacityForever_Animation:(float)time
{
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"];//必須寫opacity才行钠糊。
animation.fromValue = [NSNumber numberWithFloat:1.0f];
animation.toValue = [NSNumber numberWithFloat:0.0f];//這是透明度挟秤。
animation.autoreverses = YES;
animation.duration = time;
animation.repeatCount = MAXFLOAT;
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
animation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];///沒有的話是均勻的動(dòng)畫。
return animation;
}
/**
- CABasicAnimation test
*/
-
(void)demoViewBasicAnimation
{
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];animation.fromValue = [NSValue valueWithCGPoint:CGPointMake(_demoView.center.x, _demoView.center.y)]; //可以省略...
animation.toValue = [NSValue valueWithCGPoint:CGPointMake(270, 410)];
animation.duration = 3.0f;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; //動(dòng)畫速度設(shè)置
animation.fillMode = kCAFillModeForwards;
animation.removedOnCompletion = NO;[_demoView.layer addAnimation:animation forKey:nil];
}
/**
- CAKeyframeAnimation test
*/
-
(void)demoViewKeyframeAnimation
{
_demoView.layer.anchorPoint = CGPointMake(0.5, 0.0);
CAKeyframeAnimation *animaiton = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"];NSArray *rotationVelues = @[@(M_PI_4), @(-M_PI_4), @(M_PI_4)];
animaiton.values = rotationVelues;
animaiton.duration = 3.0f;
animaiton.repeatCount = HUGE_VALF; // #define HUGE_VALF 1e50f[_demoView.layer addAnimation:animaiton forKey:nil];
}
/**
- The animation used Bezierpath
*/
-
(void)demoViewBezierPathAnimation
{
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:_demoView.center]; //一定要設(shè)置 不然底層的CGPath找不到起始點(diǎn)抄伍,將會(huì)崩潰
[path addCurveToPoint:CGPointMake(270, 410) controlPoint1:CGPointMake(0, 460) controlPoint2:CGPointMake(320, 0)]; //以左下角和右上角為控制點(diǎn)CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
animation.path = path.CGPath;
animation.duration = 3.0f;
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;[_demoView.layer addAnimation:animation forKey:nil];
}
@end