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文档

原文地址:https://www.cnblogs.com/yangmx/p/3532931.html