iOS动画

1、Core Animation

Core Animation,即为核心动画,它是一组非常强大的动画处理API,使用它能做出非常炫丽的动画效果,而且往往是事半功倍。也就是说,使用少量的代码就可以实现非常强大的功能。Core Animation可以用在Mac OS X和iOS平台。Core Animation的动画执行过程都是在后台操作的,不会阻塞主线程。要注意的是,Core Animation是直接作用在CALayer上的,并非UIView。

QuartzCore.framework框架

CAAnimation{

        CAPropertyAnimation{

            CABasicAnimation{

                CASpringAnimation

            }

            CAKeyframeAnimation

        }

        CATransition

        CAAnimationGroup

    }

CAAnimation是所有动画对象的父类,负责控制动画的持续时间和速度,是个抽象类,不能直接使用,应该使用它具体的子类。

CAPropertyAnimation,是CAAnimation的子类,也是个抽象类,要想创建动画对象,应该使用它的两个子类:CABasicAnimation和CAKeyframeAnimation。

CABasicAnimation,是CAPropertyAnimation的子类,其子类是CASpringAnimation,它主要用于制作比较单一的动画,例如,平移、缩放、旋转、颜色渐变、边框的值的变化等,也就是将layer的某个属性值从一个值到另一个值的变化。类似x -> y这种变化,然而对于x -> y -> z甚至更多的变化是不行的。

1.移动动画

UIView*moveView = [[UIViewalloc]initWithFrame:CGRectMake(100,100,100,100)];

    moveView.backgroundColor = [UIColor redColor];

    [self.viewaddSubview:moveView];


    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];

    animation.duration=2;

    animation.repeatCount=2;

    animation.beginTime=CACurrentMediaTime() +1;// 1秒后执行

    animation.fromValue= [NSValuevalueWithCGPoint:moveView.layer.position];// 起始帧

    animation.toValue=

    [NSValue valueWithCGPoint:CGPointMake(300, 300)]; // 终了帧

    // 视图添加动画

    [moveView.layeraddAnimation:animationforKey:@"move"];

2.旋转动画

UIView*moveView = [[UIViewalloc]initWithFrame:CGRectMake(100,100,100,100)];

    moveView.backgroundColor = [UIColor redColor];

    [self.viewaddSubview:moveView];


    // 对Y轴进行旋转(指定Z轴的话,就和UIView的动画一样绕中心旋转)

    CABasicAnimation*animation =

    [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];

    animation.duration=2;

    animation.repeatCount=2;

    animation.beginTime=CACurrentMediaTime() +1;// 1秒后执行

    animation.fromValue= [NSNumbernumberWithFloat:0.0];// 起始角度

    animation.toValue= [NSNumbernumberWithFloat:M_PI];// 终止角度

    [moveView.layeraddAnimation:animationforKey:@"rotate"];

3.缩放动画

UIView*moveView = [[UIViewalloc]initWithFrame:CGRectMake(100,100,100,100)];

    moveView.backgroundColor = [UIColor redColor];

    [self.viewaddSubview:moveView];


    CABasicAnimation*animation =

    [CABasicAnimation animationWithKeyPath:@"transform.scale"];

    animation.duration=2.5;// 动画持续时间

    animation.repeatCount=2;// 重复次数

    animation.fromValue= [NSNumbernumberWithFloat:1.0];// 开始时的倍率

    animation.toValue= [NSNumbernumberWithFloat:2.0];// 结束时的倍率

    [moveView.layeraddAnimation:animationforKey:@"scale"];

4.渐隐动画

UIView*moveView = [[UIViewalloc]initWithFrame:CGRectMake(100,100,100,100)];

    moveView.backgroundColor = [UIColor redColor];

    [self.viewaddSubview:moveView];


    //opacity 指layer的透明度

    CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];

    basicAnimation.fromValue=@(1.0);

    basicAnimation.toValue = @(0.0);//[NSNumber numberWithFloat:0.0]

    basicAnimation.repeatCount=2;

    basicAnimation.duration=2;

    [moveView.layeraddAnimation:basicAnimationforKey:@"op"];

4.颜色渐变

UIView*moveView = [[UIViewalloc]initWithFrame:CGRectMake(100,100,100,100)];

    moveView.backgroundColor = [UIColor redColor];

    [self.viewaddSubview:moveView];


    CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"backgroundColor"];

    animation.duration=2;

    animation.repeatCount=2;

    animation.beginTime=CACurrentMediaTime() +1;// 1秒后执行

    animation.fromValue= (__bridgeid_Nullable)([UIColorredColor].CGColor);

    animation.toValue= (__bridgeid_Nullable)([UIColorpurpleColor].CGColor);

    [moveView.layeraddAnimation:animationforKey:@"bgcolor"];


5.组合动画

UIView*moveView = [[UIViewalloc]initWithFrame:CGRectMake(100,100,100,100)];

    moveView.backgroundColor = [UIColor redColor];

    [self.viewaddSubview:moveView];


    CABasicAnimation * animation1 = [CABasicAnimation animationWithKeyPath:@"transform.translation.x"];

    animation1.toValue= [NSNumbernumberWithFloat:80];;// 終点

    CABasicAnimation * animation2 =[CABasicAnimation animationWithKeyPath:@"transform.translation.z"];

    animation2.fromValue= [NSNumbernumberWithFloat:0.0];// 开始时的角度

    animation2.toValue= [NSNumbernumberWithFloat:M_PI];// 结束时的角度


    /* 动画组 */

    CAAnimationGroup *group = [CAAnimationGroup animation];

    group.duration=1.0;

    group.repeatCount=1;

    group.animations=

    [NSArrayarrayWithObjects:animation1, animation2,nil];

    [moveView.layeraddAnimation:groupforKey:@"move-rotate"];

触摸控制

-(void)move:(CGPoint)position{

    CASpringAnimation *animation = [CASpringAnimation animationWithKeyPath:@"position"];

    animation.fromValue= [NSValuevalueWithCGPoint:self.moveView.center];

    animation.toValue= [NSValuevalueWithCGPoint:position];

    //    设置fillModel 必须设置 removedOnCompletion

    animation.removedOnCompletion = NO;

    animation.fillMode = kCAFillModeBoth;

    [self.moveView.layeraddAnimation:animationforKey:@"move"];

}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent*)event{

    [self move:[[touches anyObject]locationInView:self.view]];

}

停在终点

animation.removedOnCompletion = NO;

    animation.fillMode = kCAFillModeForwards;

捕获动画开始时和终了时的事件

- (void)animationDidStart:(CAAnimation *)theAnimation {

 }

- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag {

 }

动画表


所有动画类型


CASpringAnimation 是CABasicAnimation的子类 弹簧动画

self.moveView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];

    self.moveView.backgroundColor = [UIColor redColor];

    [self.viewaddSubview:self.moveView];

    CASpringAnimation *animation = [CASpringAnimation animationWithKeyPath:@"bounds"];

    animation.toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, CGRectGetWidth(self.moveView.frame)*1.5, CGRectGetHeight(self.moveView.frame)*1.5)];

    animation.mass=2;

    //阻力

    animation.damping=3;

    //初始速率

    animation.initialVelocity=50;

    //刚度

    animation.stiffness=100;

    //持续时间

    animation.duration= animation.settlingDuration;

    [self.moveView.layeraddAnimation:animationforKey:@"jamp"];


CAKeyframeAnimation,是CAPropertyAnimation的子类

value形式

self.moveView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];

    self.moveView.backgroundColor = [UIColor redColor];

    [self.viewaddSubview:self.moveView];


    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];

    //设置value

    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, 300)];

    NSValue *value6=[NSValue valueWithCGPoint:CGPointMake(200, 400)];

    animation.values=@[value1,value2,value3,value4,value5,value6];

    //重复次数 默认为1

    animation.repeatCount=MAXFLOAT;

    //设置是否原路返回默认为不

    animation.autoreverses=YES;

    //设置移动速度,越小越快

    animation.duration=4.0f;

    animation.removedOnCompletion = NO;

    animation.fillMode = kCAFillModeForwards;

    animation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

    animation.delegate=self;

    //给这个view加上动画效果

    [self.moveView.layeraddAnimation:animationforKey:nil];

path形式

self.moveView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];

    self.moveView.backgroundColor = [UIColor redColor];

    [self.viewaddSubview:self.moveView];


    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];

    //创建一个CGPathRef对象,就是动画的路线

    CGMutablePathRef path = CGPathCreateMutable();

    //自动沿着弧度移动

    CGPathAddEllipseInRect(path, NULL, CGRectMake(150, 200, 200, 100));

    //设置开始位置

    CGPathMoveToPoint(path,NULL,100,100);

    //沿着直线移动

    CGPathAddLineToPoint(path,NULL, 200, 100);

    CGPathAddLineToPoint(path,NULL, 200, 200);

    CGPathAddLineToPoint(path,NULL, 100, 200);

    CGPathAddLineToPoint(path,NULL, 100, 300);

    CGPathAddLineToPoint(path,NULL, 200, 400);

    //沿着曲线移动

    CGPathAddCurveToPoint(path,NULL,50.0,275.0,150.0,275.0,70.0,120.0);

    CGPathAddCurveToPoint(path,NULL,150.0,275.0,250.0,275.0,90.0,120.0);

    CGPathAddCurveToPoint(path,NULL,250.0,275.0,350.0,275.0,110.0,120.0);

    CGPathAddCurveToPoint(path,NULL,350.0,275.0,450.0,275.0,130.0,120.0);

    animation.path=path;

    CGPathRelease(path);

    animation.autoreverses=YES;

    animation.repeatCount=MAXFLOAT;

    animation.removedOnCompletion = NO;

    animation.fillMode = kCAFillModeForwards;

    animation.duration=4.0f;

    animation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

    animation.delegate=self;

    [self.moveView.layeraddAnimation:animationforKey:nil];

一般推荐UI框架自带的贝塞尔曲线,可以用以下代码替换CGMutablePathRef那一段,代码如下:

// ②.1创建路径

    UIBezierPath * path = [UIBezierPath bezierPathWithRect:CGRectMake(75, 75, 200, 200)];

    // ②.2设置路径的属性

    // ②.3将路径设置给动画

    [animation setPath:path.CGPath];

创建一个模仿删除App的晃动动画:

// ①.初始化动画属性

    CAKeyframeAnimation * animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"];// 旋转(旋转摇晃)

    // ②.设置动画属性 ⭐️思路:摇晃,从一个点,摇晃到另一个点

    // ②.1定义角度值

    // NSArray * array = @[角度数值]

    CGFloat angle = M_PI_4 / 9.0;// 每次抖动5度

    NSArray * array = @[@(angle),@(-angle),@(angle)];// 开始角度,经过角度,回复角度 相当于 左、右、左 然后重复

    // ②.2设置动画数组

    [animation setValues:array];

    // 修改动画的填充方法

    [animation setFillMode:kCAFillModeForwards];

    [animation setRemovedOnCompletion:NO];

    // 设置时长

    animation.duration = 0.2f;

    // 设置重复

    [animation setRepeatCount:MAXFLOAT];

    // 反转动画

    // ③.将动画添加到图层

    [demoView.layer addAnimation:animation forKey:nil];


CAAnimationGroup,CAAnimation的子类,可以保存一组动画对象,将CAAnimationGroup对象加入层后,组中所有动画对象可以同时并发运行

self.moveView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];

    self.moveView.backgroundColor = [UIColor redColor];

    [self.viewaddSubview:self.moveView];


    CAAnimationGroup *group = [CAAnimationGroup animation];

    // 平移

    CABasicAnimation *anim = [CABasicAnimation animation];

    anim.keyPath=@"position";

    anim.toValue = [NSValue valueWithCGPoint:CGPointMake(arc4random_uniform(200), arc4random_uniform(500))];

    // 缩放

    CABasicAnimation *anim1 = [CABasicAnimation animation];

    anim1.keyPath = @"transform.scale";

    // 0 ~ 1

    staticCGFloatscale =0.1;

    if(scale <1) {

        scale =1.5;

    }else{

        scale =0.2;

    }

    anim1.toValue=@(scale);

    // 旋转

    CABasicAnimation *anim2 = [CABasicAnimation animation];

    anim2.keyPath = @"transform.rotation";

    anim2.toValue=@(arc4random_uniform(360) /180.0*M_PI);

    group.animations=@[anim,anim1,anim2];

    group.duration=0.5;

    // 取消反弹

    // 告诉在动画结束的时候不要移除

    group.removedOnCompletion = NO;

    // 始终保持最新的效果

    group.fillMode = kCAFillModeForwards;

    [self.moveView.layer addAnimation:group forKey:nil];


CATransition,CAAnimation的子类,用于做转场动画,能够为层提供移出屏幕和移入屏幕的动画效果。iOS比Mac OS X的转场动画效果少一点。UINavigationController就是通过CATransition实现了将控制器的视图推入屏幕的动画效果。

CATransition的type属性   

 1.#define定义的常量   

     kCATransitionFade   交叉淡化过渡   

     kCATransitionMoveIn 新视图移到旧视图上面   

     kCATransitionPush   新视图把旧视图推出去   

     kCATransitionReveal 将旧视图移开,显示下面的新视图   

 2.用字符串表示   

     pageCurl            向上翻一页   

     pageUnCurl          向下翻一页   

     rippleEffect        滴水效果   

     suckEffect          收缩效果,如一块布被抽走   

     cube                立方体效果   

     oglFlip             上下翻转效果 

subtype的属性

kCATransitionFromRight,右

kCATransitionFromLeft,左

kCATransitionFromTop,上

kCATransitionFromBottom,下

// 转场动画

    CATransition *animation = [CATransition animation];

    animation.duration=0.6;

    animation.fillMode = kCAFillModeForwards;

    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault];

    // 转场效果-动画类型type 动画方向subtype

    NSIntegerindex =0;

    if(0== index)

    {

        animation.type=@"cube";

        animation.subtype = kCATransitionFromLeft;

    }

    elseif(1== index)

    {

        animation.type=@"moveIn";

        animation.subtype = kCATransitionFromLeft;

    }

    elseif(2== index)

    {

        animation.type=@"reveal";

        animation.subtype = kCATransitionFromLeft;

    }

    elseif(3== index)

    {

        animation.type=@"fade";

        animation.subtype = kCATransitionFromLeft;

    }

    elseif(4== index)

    {

        animation.type=@"pageCurl";

        animation.subtype = kCATransitionFromLeft;

    }

    elseif(5== index)

    {

        animation.type=@"pageUnCurl";

        animation.subtype = kCATransitionFromRight;

    }

    elseif(6== index)

    {

        animation.type=@"suckEffect";

        animation.subtype = kCATransitionFromLeft;

    }

    elseif(7== index)

    {

        animation.type=@"rippleEffect";

        animation.subtype = kCATransitionFromLeft;

    }

    elseif(8== index)

    {

        animation.type=@"oglFlip";

        animation.subtype = kCATransitionFromLeft;

    }

    elseif(9== index)

    {

        animation.type=@"rotate";

        animation.subtype=@"90cw";

    }

    elseif(10== index)

    {

        animation.type=@"push";

        animation.subtype = kCATransitionFromLeft;

    }

    elseif(11== index)

    {

        animation.type = @"cameraIrisHollowOpen";

        animation.subtype = kCATransitionFromLeft;

    }

    elseif(12== index)

    {

        animation.type = @"cameraIrisHollowClose";

        animation.subtype = kCATransitionFromLeft;

    }

    elseif(13== index)

    {

        animation.type=@"kCATransitionFade";

        animation.subtype = kCATransitionFromLeft;

    }

    elseif(14== index)

    {

        animation.type = @"kCATransitionMoveIn";

        animation.subtype = kCATransitionFromLeft;

    }

    elseif(15== index)

    {

        animation.type=@"kCATransitionPush";

        animation.subtype = kCATransitionFromLeft;

    }

    elseif(16== index)

    {

        animation.type = @"kCATransitionReveal";

        animation.subtype = kCATransitionFromLeft;

    }

    // 添加转场动画到导航视图控制上

    [self.navigationController.view.layer addAnimation:animation forKey:nil];


    TestViewController *vc = [[TestViewController alloc] init];

    [self.navigationController pushViewController:vc animated:YES];

转场Demo参考地址:https://github.com/potato512/SYAnimation


2、UIView动画

UIKit自己封装了一套动画api

@interfaceUIView(UIViewAnimation)

+ (void)beginAnimations:(nullable NSString *)animationID context:(nullable void*)context;  // additional context info passed to will start/did stop selectors. begin/commit can be nested

+ (void)commitAnimations;                                                // starts up any animations when the top level animation is commited

// no getters. if called outside animation block, these setters have no effect.

+ (void)setAnimationDelegate:(nullableid)delegate;                          // default = nil

+ (void)setAnimationWillStartSelector:(nullable SEL)selector;                // default = NULL. -animationWillStart:(NSString *)animationID context:(void *)context

+ (void)setAnimationDidStopSelector:(nullable SEL)selector;                  // default = NULL. -animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context

+ (void)setAnimationDuration:(NSTimeInterval)duration;              // default = 0.2

+ (void)setAnimationDelay:(NSTimeInterval)delay;                    // default = 0.0

+ (void)setAnimationStartDate:(NSDate*)startDate;                  // default = now ([NSDate date])

+ (void)setAnimationCurve:(UIViewAnimationCurve)curve;              // default = UIViewAnimationCurveEaseInOut

+ (void)setAnimationRepeatCount:(float)repeatCount;                // default = 0.0.  May be fractional

+ (void)setAnimationRepeatAutoreverses:(BOOL)repeatAutoreverses;    // default = NO. used if repeat count is non-zero

+ (void)setAnimationBeginsFromCurrentState:(BOOL)fromCurrentState;  // default = NO. If YES, the current view position is always used for new animations -- allowing animations to "pile up" on each other. Otherwise, the last end state is used for the animation (the default).

+ (void)setAnimationTransition:(UIViewAnimationTransition)transition forView:(UIView*)view cache:(BOOL)cache;  // current limitation - only one per begin/commit block

+ (void)setAnimationsEnabled:(BOOL)enabled;                        // ignore any attribute changes while set.

#if UIKIT_DEFINE_AS_PROPERTIES

@property(class, nonatomic, readonly) BOOL areAnimationsEnabled;

#else

+ (BOOL)areAnimationsEnabled;

#endif

+ (void)performWithoutAnimation:(void(NS_NOESCAPE^)(void))actionsWithoutAnimationNS_AVAILABLE_IOS(7_0);

#if UIKIT_DEFINE_AS_PROPERTIES

@property(class,nonatomic,readonly)NSTimeIntervalinheritedAnimationDurationNS_AVAILABLE_IOS(9_0);

#else

+ (NSTimeInterval)inheritedAnimationDuration NS_AVAILABLE_IOS(9_0);

#endif

@end

@interfaceUIView(UIViewAnimationWithBlocks)

+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void(^)(void))animations completion:(void(^__nullable)(BOOLfinished))completionNS_AVAILABLE_IOS(4_0);

+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void(^)(void))animations completion:(void(^__nullable)(BOOLfinished))completionNS_AVAILABLE_IOS(4_0);// delay = 0.0, options = 0

+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void(^)(void))animationsNS_AVAILABLE_IOS(4_0);// delay = 0.0, options = 0, completion = NULL

/* Performs `animations` using a timing curve described by the motion of a spring. When `dampingRatio` is 1, the animation will smoothly decelerate to its final model values without oscillating. Damping ratios less than 1 will oscillate more and more before coming to a complete stop. You can use the initial spring velocity to specify how fast the object at the end of the simulated spring was moving before it was attached. It's a unit coordinate system, where 1 is defined as travelling the total animation distance in a second. So if you're changing an object's position by 200pt in this animation, and you want the animation to behave as if the object was moving at 100pt/s before the animation started, you'd pass 0.5. You'll typically want to pass 0 for the velocity. */ 

+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay usingSpringWithDamping:(CGFloat)dampingRatio initialSpringVelocity:(CGFloat)velocity options:(UIViewAnimationOptions)options animations:(void(^)(void))animations completion:(void(^__nullable)(BOOLfinished))completionNS_AVAILABLE_IOS(7_0);

+ (void)transitionWithView:(UIView*)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void(^__nullable)(void))animations completion:(void(^__nullable)(BOOLfinished))completionNS_AVAILABLE_IOS(4_0);

+ (void)transitionFromView:(UIView*)fromView toView:(UIView*)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void(^__nullable)(BOOLfinished))completionNS_AVAILABLE_IOS(4_0);// toView added to fromView.superview, fromView removed from its superview

/* Performs the requested system-provided animation on one or more views. Specify addtional animations in the parallelAnimations block. These additional animations will run alongside the system animation with the same timing and duration that the system animation defines/inherits. Additional animations should not modify properties of the view on which the system animation is being performed. Not all system animations honor all available options.

 */

+ (void)performSystemAnimation:(UISystemAnimation)animation onViews:(NSArray<__kindofUIView*> *)views options:(UIViewAnimationOptions)options animations:(void(^__nullable)(void))parallelAnimations completion:(void(^__nullable)(BOOLfinished))completionNS_AVAILABLE_IOS(7_0);

@end

@interfaceUIView (UIViewKeyframeAnimations)

+ (void)animateKeyframesWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewKeyframeAnimationOptions)options animations:(void(^)(void))animations completion:(void(^__nullable)(BOOLfinished))completionNS_AVAILABLE_IOS(7_0);

+ (void)addKeyframeWithRelativeStartTime:(double)frameStartTime relativeDuration:(double)frameDuration animations:(void (^)(void))animations NS_AVAILABLE_IOS(7_0); // start time and duration are values between 0.0 and 1.0 specifying time and duration relative to the overall time of the keyframe animation

@end

例子

1.普通方式

[UIView beginAnimations:@"firstAnimation" context:nil];

//动画持续时间

    [UIView setAnimationDuration:2.f];

    //动画的代理对象

    [UIView setAnimationDelegate:self];

    //设置动画将开始时代理对象执行的SEL

    [UIViewsetAnimationWillStartSelector:@selector(startAnimation:)];

    [UIViewsetAnimationDidStopSelector:@selector(stopAnimation:)];

    //设置动画延迟执行的时间

    [UIView setAnimationDelay:0.f];

    //设置动画的重复次数

    [UIView setAnimationRepeatCount:4];

    //设置开始动画的时间,默认是now

    [UIView setAnimationStartDate:[NSDate date]];


    //设置动画的曲线

    /*

         UIViewAnimationCurve的枚举值:

         UIViewAnimationCurveEaseInOut,        // 慢进慢出(默认值)

         UIViewAnimationCurveEaseIn,            // 慢进

         UIViewAnimationCurveEaseOut,          // 慢出

         UIViewAnimationCurveLinear            // 匀速

         */

    [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];


    //设置是否从当前状态开始播放动画

    /*假设上一个动画正在播放,且尚未播放完毕,我们将要进行一个新的动画:

         当为YES时:动画将从上一个动画所在的状态开始播放

         当为NO时:动画将从上一个动画所指定的最终状态开始播放(此时上一个动画马上结束)*/

    [UIView setAnimationBeginsFromCurrentState:YES];


    //设置动画是否继续执行相反的动画

    [UIView setAnimationRepeatAutoreverses:NO];

    //是否使用动画效果(对象属性依然会被改变,只是没有动画效果)YES使用;NO禁用

    [UIView setAnimationsEnabled:YES];


    //设置视图的过渡效果

    /* 第一个参数:UIViewAnimationTransition的枚举值如下

         UIViewAnimationTransitionNone,              //不使用动画

         UIViewAnimationTransitionFlipFromLeft,      //从左向右旋转翻页

         UIViewAnimationTransitionFlipFromRight,    //从右向左旋转翻页

         UIViewAnimationTransitionCurlUp,            //从下往上卷曲翻页

         UIViewAnimationTransitionCurlDown,          //从上往下卷曲翻页

         第二个参数:需要过渡效果的View

         第三个参数:是否使用视图缓存,YES:视图在开始和结束时渲染一次;NO:视图在每一帧都渲染*/

    [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:[[UIView alloc] initWithFrame:CGRectZero] cache:YES];

    结束动画方法:    [UIView commitAnimations];


2.Block方式

[UIView animateWithDuration:1.0

                          delay:2.0

                        options:UIViewAnimationOptionCurveLinear

                     animations:^{

        //执行的动画代码

    }

                     completion:^(BOOLfinished) {

        //动画执行完成之后的回调

    }];


spring动画

/**

     *  第一个参数:动画持续时间

     *  第二个参数:动画延时开始的时间

     *  第三个参数:Spring动画,震动效果,范围0~1,数值越小震动效果越明显

     *  第四个参数:初始速度,数值越大初始速度越快

     *  第五个参数:动画的过渡效果

     *  第六个参数:执行的动画代码

     *  第七个参数:动画执行完成之后的回调

     */

    [UIView animateWithDuration:1.0

                          delay:2.0

         usingSpringWithDamping:0.5

          initialSpringVelocity:100.f

                        options:UIViewAnimationOptionCurveLinear

                     animations:^{

                     }

                     completion:^(BOOLfinished) {

                     }];


3.转场动画

    //单视图转场动画

    + (void)transitionWithView:(UIView *)view

duration:(NSTimeInterval)duration

options:(UIViewAnimationOptions)options

animations:(void(^__nullable)(void))animations

completion:(void(^__nullable)(BOOLfinished))completion

    //双视图转场动画

    + (void)transitionFromView:(UIView *)fromView

toView:(UIView *)toView

duration:(NSTimeInterval)duration

options:(UIViewAnimationOptions)options

completion:(void(^__nullable)(BOOLfinished))completion

这两个都是转场动画,不同的是第一个是单视图转场,第二个是双视图转场.不过需要注意的是:单视图转场动画只能用作属性动画做不到的转场效果,比如属性动画不能给UIImageview的image赋值操作做动画效果等.

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

推荐阅读更多精彩内容