CABasicAnimation 动画

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];
    }

/*!
设定动画
属性 说明
duration 动画的时长
repeatCount 重复的次数。不停重复设置为 HUGE_VALF
repeatDuration 设置动画的时间。在该时间内动画一直执行,不计次数。
beginTime 指定动画开始的时间。从开始延迟几秒的话,设置为【CACurrentMediaTime() + 秒数】 的方式
timingFunction 设置动画的速度变化
autoreverses 动画结束时是否执行逆动画
fromValue 所改变属性的起始值
toValue 所改变属性的结束时的值
byValue 所改变属性相同起始值的改变量
removedOnCompletion 防止动画结束后回到初始状态 所以为了使动画结束之后layer保持结束状态,应将removedOnCompletion设置为NO
fillMode 防止动画结束后回到初始状态 该属性定义了你的动画在开始和结束时的动作。默认值是 kCAFillModeRemoved。
speed speed 改变动画的速度 可以直接设置动画上的speed属性,这样只有这个动画速度。
speed两点需注意的:
(1)如果设置动画时间为4s,speed设置为2,则动画只需2s即可执行完。
(2)如果同时设置了动画的speed和layer 的speed,则实际的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;//协议
animaiton.delegate = [[AnimationDelegate alloc]init];

// 防止动画结束后回到初始状态
animaiton.removedOnCompletion = NO;
animaiton.fillMode = kCAFillModeForwards;

/*!
 kCAFillModeForwards    kCAFillModeForwards 设置为该值,动画即使之后layer的状态将保持在动画的最后一帧,而removedOnCompletion的默认属性           
                        值是 YES,所以为了使动画结束之后layer保持结束状态,应将removedOnCompletion设置为NO。
 kCAFillModeBackwards   kCAFillModeBackwards 设置为该值,将会立即执行动画的第一帧,不论是否设置了 beginTime属性。观察发现,设置该值,刚开
                        始视图不见,还不知道应用在哪里。
 kCAFillModeBoth        kCAFillModeBoth 该值是 kCAFillModeForwards 和 kCAFillModeBackwards的组合状态
 kCAFillModeRemoved     kCAFillModeRemoved 设置为该值,动画将在设置的 beginTime 开始执行(如没有设置beginTime属性,则动画立即执行),动
                        画执行完成后将会layer的改变恢复原状。
 */
/*
 kCAMediaTimingFunctionLinear           传这个值,在整个动画时间内动画都是以一个相同的速度来改变。也就是匀速运动。
 kCAMediaTimingFunctionEaseIn           使用该值,动画开始时会较慢,之后动画会加速。
 kCAMediaTimingFunctionEaseOut          使用该值,动画在开始时会较快,之后动画速度减慢。
 kCAMediaTimingFunctionEaseInEaseOut    使用该值,动画在开始和结束时速度较慢,中间时间段内速度较快。
 kCAMediaTimingFunctionDefault

 */
//添加动画
[_demoView.layer addAnimation:animaiton forKey:@"Animation"];

}

//其实比较重要的是有多个动画的时候如何在代理方法中区分不同的动画
//方式一:
//如果我们添加动画的视图是全局变量,可使用该方法。
//添加动画时,我们使用了

//动画开始时

  • (void)animationDidStart:(CAAnimation *)anim
    {
    if ([anim isEqual:[_demoView.layer animationForKey:@"Animation"]]) {
    NSLog(@"动画组执行了");
    }
    }

//动画结束时

  • (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
    {
    //方法中的flag参数表明了动画是自然结束还是被打断,比如调用了removeAnimationForKey:方法或removeAnimationForKey方法,flag为NO,如果是正常结束,flag为YES。
    NSLog(@"结束了");
    }

//方式二
//添加动画的视图是局部变量时,可使用该方法
//添加动画给动画设置key-value对
-(void)animationCustomDidStart{
// [positionAnima setValue:@"PositionAnima" forKey:@"AnimationKey"];
// [transformAnima setValue:@"TransformAnima" forKey:@"AnimationKey"];
}
//动画结束时
//- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
//{
// if ([[anim valueForKey:@"AnimationKey"]isEqualToString:@"PositionAnima"]) {
// NSLog(@"位置移动动画执行结束");
// }
// else if ([[anim valueForKey:@"AnimationKey"]isEqualToString:@"TransformAnima"]){
// NSLog(@"旋转动画执行结束");
// }
//}

//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 中心点旋转
-(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 - 我的旋转 顺时针

-(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;//不设置时候的话,有一个默认的缩放时间.
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
return animation;
}

pragma mark ====旋转动画======

-(CABasicAnimation *)rotation:(float)dur degree:(float)degree direction:(int)direction repeatCount:(int)repeatCount
{
//第一个参数是旋转角度,后面三个参数形成一个围绕其旋转的向量,起点位置由UIView的center属性标识。
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 === 永久闪烁的动画 ======

-(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];///没有的话是均匀的动画。
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]; //动画速度设置
    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]; //一定要设置 不然底层的CGPath找不到起始点,将会崩溃
    [path addCurveToPoint:CGPointMake(270, 410) controlPoint1:CGPointMake(0, 460) controlPoint2:CGPointMake(320, 0)]; //以左下角和右上角为控制点

    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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,569评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,499评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,271评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,087评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,474评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,670评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,911评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,636评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,397评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,607评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,093评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,418评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,074评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,092评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,865评论 0 196
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,726评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,627评论 2 270

推荐阅读更多精彩内容