• 17-UIKit(UIView的动画)


    2. UIView的动画

    UIView类本身具有动画的功能

        2.1 概念

            由UI对底层Core Animation框架的封装

            可以轻松简单的实现动画效果

        2.2 两种使用方式

            1> Block

                基本步骤

                    1>设置参与动画的视图的初始状态   alpha=0.0

                    2>[UIView animateWithDuration:]

                    3>将结束状态写到block中

     例1

    - (IBAction)start:(id)sender {
        [UIView animateWithDuration:3.0 animations:^{
            self.imageView.alpha = 1.0;// 目标值
        }];
    }

    例2

    // 界面显示后调用此方法,一般用来设置动画
    -(void)viewDidAppear:(BOOL)animated{
        // label动画
        [super viewDidAppear:animated];
        CGRect endFrame = self.label.frame;
        CGRect startFrame = endFrame;
        startFrame.origin.x = - self.label.frame.size.width;
        self.label.frame = startFrame;// frame开始值
        self.label.alpha = 0;// 透明度开始值
        [UIView animateWithDuration:2.0 animations:^{
            self.label.frame = endFrame;// frame结束值
            self.label.alpha = 1.0;// 透明度结束值
        }];
        // 飞机入场
        self.imageView.image = [UIImage animatedImageNamed:@"ship-anim" duration:1.0];
        endFrame = self.imageView.frame;
        startFrame = endFrame;
        startFrame.origin.y = self.view.frame.size.height;
        self.imageView.frame = startFrame;
        [UIView animateWithDuration:2.0 animations:^{
            self.imageView.frame = endFrame;
        }];
    }
    - (IBAction)start:(id)sender {
        CGPoint center = self.imageView.center;
        center.y -= 250;
    //    CGAffineTransform transform = CGAffineTransformRotate(self.imageView.transform, M_PI);
    //    CGAffineTransform transform = CGAffineTransformMakeScale(1.5, 1.5);
        // Duration动画时长 delay延迟
        [UIView animateWithDuration:2.0 delay:0 options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat animations:^{
            self.imageView.center = center;
    //        self.imageView.transform = transform;
        } completion:nil];
        
    }
    
    - (IBAction)back:(id)sender {
        CGRect endFrame = self.imageView.frame;
        endFrame.origin.y += 250;
        [UIView animateWithDuration:1.0 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
            self.imageView.frame = endFrame;
        } completion:nil];
    }

    例3

    -(void)viewDidAppear:(BOOL)animated{
        [super viewDidAppear:animated];
        [self animateOnView:self.imageView duration:1.0 clockWise:NO];// clockWise  YES顺时针
    }
    -(void)animateOnView:(UIView *)view duration:(NSTimeInterval)duration clockWise:(BOOL)clockWise{
        // completion动画结束要做的事
        [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
            view.transform = CGAffineTransformRotate(view.transform, M_PI_2 * (clockWise ? 1 : -1));
        } completion:^(BOOL finished) {
            if (!self.needStoped) {
                // 递归调用
                [self animateOnView:view duration:duration clockWise:clockWise];
            }
        }];
    }
    // 停止动画
    - (IBAction)stopAnimation:(id)sender {
        self.needStoped = YES;
    }
    // 恢复动画
    - (IBAction)startAnimation:(id)sender {
        self.needStoped = NO;
        [self viewDidAppear:YES];
    }

           2> Commit

    -(void)viewDidAppear:(BOOL)animated{
        [super viewDidAppear:animated];
        // 1开始一个动画,给动画起个名字,
        [UIView beginAnimations:@"snow" context:nil];
        // 2设置动画相关属性
        [UIView setAnimationDuration:4.0];
        [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
        // 3动画目标值
        self.snow.center = CGPointMake(self.snow.center.x, self.view.bounds.size.height - self.snow.frame.size.height);
        // 4提交动画,动画开始
        [UIView commitAnimations];
    }

      2.3 什么属性能做动画的设置属性

            .frame

            .bounds

            .center

            .transform

            .alpha

            等

        稍复杂的动画[MX6-飘雪花练习]

    #define MAX_SIZE 10
    #define MAX_DURATION 5//速度
    #define MAX_OFFSET_X 100
    #define FPS 30
    #define DISAPPER_DURATION 2
    
    @interface MXViewController ()
    @property(nonatomic) NSInteger count;
    @property(nonatomic,strong) NSTimer *timer;
    @end
    
    @implementation MXViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(viewDidAppear:) userInfo:nil repeats:YES];
        self.timeInterVal = 1/FPS;
    }
    
    -(void)viewDidAppear:(BOOL)animated{
        [super viewDidAppear:animated];
        [NSTimer scheduledTimerWithTimeInterval:self.timeInterVal target:self selector:@selector(generatorSnow) userInfo:nil repeats:YES];
    }
    // 生成雪片
    -(void)generatorSnow{
        self.count++;
        // 创建随机大小的雪花
        NSInteger size = arc4random() % MAX_SIZE + MAX_SIZE;
        UIImageView *snow = [[UIImageView alloc] initWithFrame:CGRectMake(arc4random() % 320, 20, size, size)];
        snow.image = [UIImage imageNamed:@"snow.png"];
        snow.tag = self.count;
        // 加入到父视图中
        [self.view addSubview:snow];
        
        // 创建动画
        [UIView beginAnimations:[NSString stringWithFormat:@"%d",self.count] context:nil];
        [UIView setAnimationDuration:arc4random() % MAX_DURATION + 2];
        [UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
        
        // 设置了delegate,动画结束后才会自动调用disappearAnimate:
        [UIView setAnimationDelegate:self];
        [UIView setAnimationDidStopSelector:@selector(disappearAnimate:)];// 动画结束后调用disappearAnimate
        
        NSInteger offSetX = arc4random() % MAX_OFFSET_X - 50;
        // 设置动画目标值
        snow.center = CGPointMake(snow.center.x + offSetX, self.view.bounds.size.height - 30);
        snow.transform = CGAffineTransformMakeRotation((arc4random() % 180)/180 * M_PI * 2);
        [UIView commitAnimations];
    }
    - (IBAction)changeSnow:(UISlider *)sender {
        CGFloat value = sender.maximumValue - sender.value;
        self.timeInterVal = value * FPS;
        [self.timer invalidate];
        self.timer = [NSTimer scheduledTimerWithTimeInterval:self.timeInterVal target:self selector:@selector(generatorSnow) userInfo:nil repeats:YES];
    }
    // 雪花消失
    -(void)disappearAnimate:(NSString *)animationId{
        [UIView beginAnimations:animationId context:nil];
        [UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
        [UIView setAnimationDuration:arc4random() % DISAPPER_DURATION + 1];
        
        [UIView setAnimationDelegate:self];
        [UIView setAnimationDidStopSelector:@selector(deleteView:)];
        
        UIImageView *snow = (UIImageView *)[self.view viewWithTag:[animationId intValue]];
        snow.alpha = 0;
        [UIView commitAnimations];
    }
    // 删除雪花对象
    -(void)deleteView:(NSString *)animationId{
        UIImageView *snow = (UIImageView *)[self.view viewWithTag:[animationId intValue]];
        [snow removeFromSuperview];// 删除子视图的方式
        // NSLog(@"雪花对象:%p,雪花数量:%d",snow,[self.view subviews].count);
    }

        2.4 UIView执行动画的方法:

            [UIView animateWithDuration:duration delay:delay             options:UIViewAnimationOptionCurveEaseIn animations:^{

            self.playerView.frame = endFrame;

        } completion:nil];

       

        duration:  动画时长(秒)

        delay: 启动动画的延迟(秒)

        animations:

            设置动画结束后的状态

        completion:

            动画结束后需要做事的

        options:

        UIViewAnimationOptionCurveEaseInOut 动画先从慢到快,再从快到慢        

        UIViewAnimationOptionCurveEaseIn    越来越快          

        UIViewAnimationOptionCurveEaseOut   越来越慢   

        UIViewAnimationOptionCurveLinear    匀速

          

        UIViewAnimationOptionAllowUserInteraction  在动画期间是否允许用户交互

        UIViewAnimationOptionBeginFromCurrentState  动画要不要从当前位置开始,如果不选,那就从初始位置开始

        UIViewAnimationOptionRepeat   动画重复执行

        UIViewAnimationOptionAutoreverse   动画是否需要反向执行

     

        UIViewAnimationOptionLayoutSubviews 当动画发生大小变化时,是否需要重新布局

        UIViewAnimationOptionAllowAnimatedContent  在动画的同时要不要执行Redraw

        旋转动画

         2.5 UIView设置全局属性方式动画

        1>设置开始状态

        2>开始动画,并给动画命名

            [UIView beginAnimations:@"动画名" ….];

        3>设置动画相关属性

            [UIView setAnimationDuration:…];

            [UIView setAnimationCurve:…];

            ….

        4>设置动画结束状态

        5>提交动画

            [UIView commitsAnimation];

        注意:

            当设置了delegate后,DidStopSelector才会有效。

        [UIView setAnimationDelegate:self];

        [UIView setAnimationDidStopSelector:@selector(..)];

    3. iOS7新增DynamicAnimator

    @interface MXViewController () <UIDynamicAnimatorDelegate>
    @property(nonatomic,strong) UIDynamicAnimator *animator;//
    @property(nonatomic,strong) UIDynamicBehavior *behavior;// 行为(容器)
    @property(nonatomic,strong) UIGravityBehavior *gravity;// 重力
    @property(nonatomic,strong) UICollisionBehavior *collision;// 碰撞
    
    
    @end
    
    @implementation MXViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
    }
    -(UIGravityBehavior *)gravity{
        if (!_gravity) {
            _gravity = [[UIGravityBehavior alloc] init];
            _gravity.magnitude = 0.9;// 重力值
        }
        return _gravity;
    }
    -(UICollisionBehavior *)collision{
        if (!_collision) {
            _collision = [[UICollisionBehavior alloc] init];
            _collision.translatesReferenceBoundsIntoBoundary = YES;// 周围边界翻译为碰撞边界
        }
        return _collision;
    }
    -(UIDynamicBehavior *)behavior{
        
        if (!_behavior) {
            _behavior = [[UIDynamicBehavior alloc] init];
            [_behavior addChildBehavior:self.gravity];
            [_behavior addChildBehavior:self.collision];
        }
        return _behavior;
    }
    -(UIDynamicAnimator *)animator{
        if (!_animator) {
            _animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
            _animator.delegate = self;
        }
        return _animator;
    }
    - (IBAction)dropTap:(id)sender {
        UIView *dropView = [[UIView alloc] initWithFrame:CGRectMake(arc4random() % 320, 100, 40, 40)];
        dropView.backgroundColor = [self roundColor];
        [self.view addSubview:dropView];
        [self.gravity addItem:dropView];
        [self.collision addItem:dropView];
        [self.animator addBehavior:self.behavior];
        
    }
    -(UIColor *)roundColor{
        switch (arc4random() % 5) {
            case 0:
                return [UIColor greenColor];
                break;
            case 1:
                return [UIColor grayColor];
                break;
            case 2:
                return [UIColor redColor];
                break;
            case 3:
                return [UIColor yellowColor];
                break;
            case 4:
                return [UIColor blackColor];
                break;
            default:
                break;
        }
        return nil;
    }
    -(void)dynamicAnimatorDidPause:(UIDynamicAnimator *)animator{
        [animator removeBehavior:self.behavior];
    }

    作业:

        1. 飞机大战Demo版

            屏幕上有一个飞机,你点在屏幕的哪,飞机就飞到哪儿

        2. 模仿一个淘宝的购物车

            窗口左上角一个一图片,代表一个宝贝,点宝贝,会落入屏幕下方的一个小车车中,落下时,宝贝会越来越小,注意宝贝本身还在。

        3. 简单看看UIDynamicAnimator文档

  • 相关阅读:
    任何优秀的程序员, 都有早逝的风险
    租车App第一次迭代报告
    快租车app——需求分析心得
    结对编程——自动生成数学试卷的系统(javaswing,mysql)by 陈松&刘宇航
    结队编程之——阅读分析队友的代码(C++自动生成数学试卷)
    自动生成不同难度的数学试卷系统,并输出到txt文件中,命名为当前时间(java)
    代码之美——浅谈命名规则与代码优化
    关于防抖和节流
    关于sessionStorage和localstorage的一些记录
    vue应用微信二维码登录的一些记录
  • 原文地址:https://www.cnblogs.com/yangmx/p/3532931.html
Copyright © 2020-2023  润新知