美文网首页iOS图与文
iOS开发之UI篇(6)—— 动画效果

iOS开发之UI篇(6)—— 动画效果

作者: 看影成痴 | 来源:发表于2017-11-15 10:27 被阅读31次

    版本

    Xcode 9.1

    UIView本身封装了一些常用的动画:基础动画、关键帧动画及转场动画。对于一般的iOS开发基本能满足,如果需要更多自定义的动画效果,那就使用核心动画CoreAnimation。

    一、基础动画

    方法1:UIViewAnimation(UIView类方法)

        /* 方法1:UIViewAnimation(UIView类方法)*/
        [UIView beginAnimations:@"basicAnimation" context:nil];     // 设置动画animationID、上下文
        [UIView setAnimationDuration:5.0];      // 动画持续5秒
        [UIView setAnimationDelay:2.0];         // 2秒后执行动画
        [UIView setAnimationDelegate:self];     // 设置动画代理对象,当动画开始或者结束时会发消息给代理对象(调用相应方法)
        [UIView setAnimationWillStartSelector:@selector(start)];    // 动画开始调用方法
        [UIView setAnimationDidStopSelector:@selector(stop)];       // 动画结束调用方法
        _imageView.center = location;           // 移动坐标
        [UIView commitAnimations];              // 提交动画
    
    
    #pragma mark - UIViewAnimation代理方法
    
    - (void)start {
        
        NSLog(@"动画开始");
    }
    
    
    - (void)stop {
        
        NSLog(@"动画结束");
    }
    

    方法2:UIViewAnimationWithBlocks(block方法)

    [UIView animateWithDuration:5.0     // 动画持续时间
                              delay:0       // 延迟0秒执行
             usingSpringWithDamping:0.5     // 阻尼,范围0-1,阻尼越接近于0,弹性效果越明显
              initialSpringVelocity:1.0     // 弹性复位的速度
                            options:UIViewAnimationOptionCurveLinear
                         animations:^{
                             NSLog(@"block动画开始");
                             _imageView.center = location;
                         }
                         completion:^(BOOL finished) {
                             if (finished) {
                                 NSLog(@"block动画结束");
                             }
                         }];
    

    block方法中options枚举:

    1.常规动画属性设置(可以同时选择多个进行设置)
      UIViewAnimationOptionLayoutSubviews:动画过程中保证子视图跟随运动。
      UIViewAnimationOptionAllowUserInteraction:动画过程中允许用户交互。
      UIViewAnimationOptionBeginFromCurrentState:所有视图从当前状态开始运行。
      UIViewAnimationOptionRepeat:重复运行动画。
      UIViewAnimationOptionAutoreverse :动画运行到结束点后仍然以动画方式回到初始点。
      UIViewAnimationOptionOverrideInheritedDuration:忽略嵌套动画时间设置。
      UIViewAnimationOptionOverrideInheritedCurve:忽略嵌套动画速度设置。
      UIViewAnimationOptionAllowAnimatedContent:动画过程中重绘视图(注意仅仅适用于转场动画)。
      UIViewAnimationOptionShowHideTransitionViews:视图切换时直接隐藏旧视图、显示新视图,而不是将旧视图从父视图移除(仅仅适用于转场动画)
      UIViewAnimationOptionOverrideInheritedOptions :不继承父动画设置或动画类型。
    2.动画速度控制(可从其中选择一个设置)
      UIViewAnimationOptionCurveEaseInOut:动画先缓慢,然后逐渐加速。
      UIViewAnimationOptionCurveEaseIn :动画逐渐变慢。
      UIViewAnimationOptionCurveEaseOut:动画逐渐加速。
      UIViewAnimationOptionCurveLinear :动画匀速执行,默认值。
    3.转场类型(仅适用于转场动画设置,可以从中选择一个进行设置,基础动画、关键帧动画不需要设置)
      UIViewAnimationOptionTransitionNone:没有转场动画效果。
      UIViewAnimationOptionTransitionFlipFromLeft :从左侧翻转效果。
      UIViewAnimationOptionTransitionFlipFromRight:从右侧翻转效果。
      UIViewAnimationOptionTransitionCurlUp:向后翻页的动画过渡效果。
      UIViewAnimationOptionTransitionCurlDown :向前翻页的动画过渡效果。
      UIViewAnimationOptionTransitionCrossDissolve:旧视图溶解消失显示下一个新视图的效果。
      UIViewAnimationOptionTransitionFlipFromTop :从上方翻转效果。
      UIViewAnimationOptionTransitionFlipFromBottom:从底部翻转效果
    

    示例

    #import "ViewController.h"
    
    @interface ViewController () {
        
        UIImageView *_imageView;
    }
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        // 设置背景
        UIImageView *imageView = [[UIImageView alloc] init];
        imageView.frame = [UIScreen mainScreen].bounds;
        imageView.image = [UIImage imageNamed:@"fox.jpg"];
        imageView.contentMode = UIViewContentModeScaleAspectFit;
        [self.view addSubview:imageView];
        
        // 创建动画控件
        _imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"heart"]];
        _imageView.bounds = CGRectMake(0, 0, 50, 50);
        _imageView.center = CGPointMake(50, 50);
        [self.view addSubview:_imageView];
    }
    
    
    #pragma mark - 触摸事件
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        
        UITouch *touch = touches.anyObject;
        CGPoint location = [touch locationInView:self.view];
        
        /* 方法1:UIViewAnimation(UIView类方法)*/
    //    [UIView beginAnimations:@"basicAnimation" context:nil];     // 设置动画animationID、上下文
    //    [UIView setAnimationDuration:5.0];      // 动画持续5秒
    //    [UIView setAnimationDelay:2.0];         // 2秒后执行动画
    //    [UIView setAnimationDelegate:self];     // 设置动画代理对象,当动画开始或者结束时会发消息给代理对象(调用相应方法)
    //    [UIView setAnimationWillStartSelector:@selector(start)];    // 动画开始调用方法
    //    [UIView setAnimationDidStopSelector:@selector(stop)];       // 动画结束调用方法
    //    _imageView.center = location;           // 移动坐标
    //    [UIView commitAnimations];              // 提交动画
        
        /* 方法2:UIViewAnimationWithBlocks(block方法)*/
        [UIView animateWithDuration:5.0     // 动画持续时间
                              delay:0       // 延迟0秒执行
             usingSpringWithDamping:0.5     // 阻尼,范围0-1,阻尼越接近于0,弹性效果越明显
              initialSpringVelocity:1.0     // 弹性复位的速度
                            options:UIViewAnimationOptionCurveLinear
                         animations:^{
                             NSLog(@"block动画开始");
                             _imageView.center = location;
                         }
                         completion:^(BOOL finished) {
                             if (finished) {
                                 NSLog(@"block动画结束");
                             }
                         }];
    
    }
    
    
    #pragma mark - UIViewAnimation代理方法
    
    - (void)start {
        
        NSLog(@"动画开始");
    }
    
    
    - (void)stop {
        
        NSLog(@"动画结束");
    }
    

    基础动画效果:

    二、关键帧动画

    基础动画中只能设置首尾两个关键帧动画,即开始位置和结尾位置固定,中间以直线运动。而关键帧动画中,我们可以设置多个关键帧,使得动画更加生动真实。

    关键帧动画运动轨迹图示

    示例

    #import "ViewController.h"
    
    @interface ViewController () {
        
        UIImageView *_imageView;
    }
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        //设置背景
        UIImageView *imageView = [[UIImageView alloc] init];
        imageView.frame = [UIScreen mainScreen].bounds;
        imageView.image = [UIImage imageNamed:@"fox.jpg"];
        imageView.contentMode = UIViewContentModeScaleAspectFit;
        [self.view addSubview:imageView];
        
        //创建图像显示控件
        _imageView=[[UIImageView alloc]initWithImage:[UIImage imageNamed:@"heart.png"]];
        _imageView.bounds = CGRectMake(0, 0, 50, 50);
        _imageView.center=CGPointMake(50, 50);
        [self.view addSubview:_imageView];
    }
    
    
    #pragma mark - 触摸事件
    
    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    
        /*
         关键帧动画
         options:
             1.常规动画属性设置(可以同时选择多个进行设置)
             UIViewAnimationOptionLayoutSubviews:动画过程中保证子视图跟随运动。
             UIViewAnimationOptionAllowUserInteraction:动画过程中允许用户交互。
             UIViewAnimationOptionBeginFromCurrentState:所有视图从当前状态开始运行。
             UIViewAnimationOptionRepeat:重复运行动画。
             UIViewAnimationOptionAutoreverse :动画运行到结束点后仍然以动画方式回到初始点。
             UIViewAnimationOptionOverrideInheritedDuration:忽略嵌套动画时间设置。
             UIViewAnimationOptionOverrideInheritedOptions :不继承父动画设置或动画类型。
             2.动画模式设置(同前面关键帧动画动画模式一一对应,可以从其中选择一个进行设置)
             UIViewKeyframeAnimationOptionCalculationModeLinear:连续运算模式。
             UIViewKeyframeAnimationOptionCalculationModeDiscrete :离散运算模式。
             UIViewKeyframeAnimationOptionCalculationModePaced:均匀执行运算模式。
             UIViewKeyframeAnimationOptionCalculationModeCubic:平滑运算模式。
             UIViewKeyframeAnimationOptionCalculationModeCubicPaced:平滑均匀运算模式。
         */
        [UIView animateKeyframesWithDuration:5.0
                                       delay:0
                                     options: UIViewAnimationOptionCurveLinear | UIViewAnimationOptionCurveLinear
                                  animations:^{
                                      // 第二个关键帧(准确地说第一个关键帧是开始位置):从0秒开始持续50%的时间,也就是5.0*0.5=2.5秒
                                      [UIView addKeyframeWithRelativeStartTime:0.0
                                                              relativeDuration:0.5
                                                                    animations:^{
                                                                        _imageView.center = CGPointMake(100, 100);
                                                                    }];
                                      // 第三个关键帧,从0.5*5.0秒开始,持续5.0*0.25=1.25秒
                                      [UIView addKeyframeWithRelativeStartTime:0.5
                                                              relativeDuration:0.25
                                                                    animations:^{
                                                                        _imageView.center = CGPointMake(50, 150);
                                                                    }];
                                      // 第四个关键帧:从0.75*5.0秒开始,持所需5.0*0.25=1.25秒
                                      [UIView addKeyframeWithRelativeStartTime:0.75
                                                              relativeDuration:0.25
                                                                    animations:^{
                                                                        _imageView.center = CGPointMake(100, 200);
                                                                    }];
                                  }
                                  completion:nil];
    }
    
    
    @end
    

    关键帧动画效果:

    三、转场动画

    示例

    #define IMAGE_COUNT 3
    
    #import "ViewController.h"
    
    @interface ViewController () {
        
        UIImageView *_imageView;
        int _currentIndex;
    }
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        //定义图片控件
        _imageView = [[UIImageView alloc]init];
        _imageView.frame = [UIScreen mainScreen].bounds;
        _imageView.contentMode = UIViewContentModeScaleAspectFit;
        _imageView.image = [UIImage imageNamed:@"fox0.jpeg"];//默认图片
        [self.view addSubview:_imageView];
        
        //添加手势
        UISwipeGestureRecognizer *leftSwipeGesture=[[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(leftSwipe:)];
        leftSwipeGesture.direction=UISwipeGestureRecognizerDirectionLeft;
        [self.view addGestureRecognizer:leftSwipeGesture];
        
        UISwipeGestureRecognizer *rightSwipeGesture=[[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(rightSwipe:)];
        rightSwipeGesture.direction=UISwipeGestureRecognizerDirectionRight;
        [self.view addGestureRecognizer:rightSwipeGesture];
    }
    
    
    #pragma mark - 手势响应方法
    
    // 向左滑动浏览下一张图片
    -(void)leftSwipe:(UISwipeGestureRecognizer *)gesture{
        [self transitionAnimation:YES];
    }
    
    
    // 向右滑动浏览上一张图片
    -(void)rightSwipe:(UISwipeGestureRecognizer *)gesture{
        [self transitionAnimation:NO];
    }
    
    
    #pragma mark - 私有方法
    
    /**
     转场动画
    
     @param isNext 是否显示下一张图片
     */
    -(void)transitionAnimation:(BOOL)isNext{
        
        UIViewAnimationOptions option;
        if (isNext) {
            option = UIViewAnimationOptionCurveLinear|UIViewAnimationOptionTransitionFlipFromRight;
        }else{
            option = UIViewAnimationOptionCurveLinear|UIViewAnimationOptionTransitionFlipFromLeft;
        }
        
        [UIView transitionWithView:_imageView
                          duration:1.0
                           options:option
                        animations:^{
                            _imageView.image = [self getImage:isNext];
                        }
                        completion:nil];
    }
    
    
    /**
     取得当前图片
    
     @param isNext 是否显示下一张图片
     @return 返回图片对象
     */
    -(UIImage *)getImage:(BOOL)isNext{
        
        if (isNext) {
            _currentIndex=(_currentIndex+1)%IMAGE_COUNT;
        }else{
            _currentIndex=(_currentIndex-1+IMAGE_COUNT)%IMAGE_COUNT;
        }
        NSString *imageName=[NSString stringWithFormat:@"fox%i.jpeg",_currentIndex];
        return [UIImage imageNamed:imageName];
    }
    
    
    @end
    

    转场动画效果:

    相关文章

      网友评论

        本文标题:iOS开发之UI篇(6)—— 动画效果

        本文链接:https://www.haomeiwen.com/subject/aefcvxtx.html