zoukankan      html  css  js  c++  java
  • iOS Animation 学习(3)

    View Animation Options

    UIView的类方法 nimateWithDuration:animations: 和 animateWithDuration:animations:completion: 都是 animateWith- Duration:delay:options:animations:completion: 的缩减版,参数解析如下:

    • duration

      动画的播放时间:从开始到结束需要多长时间(以秒为单位)来运行。你也可以认为这是动画的速度。显然,如果两个视图被告知同样时间里移动至不同的距离,移动距离更远的速度更快。

    • delay

      动画开始之前的延时。默认在缩减版方法中时没有延时的。

    • options

      额外选项值结合起来的位掩码(使用按位或运算符)。

    • animations

      这个block包含属性变化的动画。

    • completion

      当动画结束时会执行这个block(可以是nil)。它有一个BOOL类型的参数来指定动画是否结束了。即使在上面的动画block中没有触发任何动画,这个block仍然会被传入YES参数来调用。你也可以在这个block中执行另外的动画。

    下面是第三个参数选项的一些值,你可能会用到:

    • Animation curve

      动画曲线描述了动画变化的过程中,如何加快。 “ease”一词意味着动画在开始和结束时,由零速度和中心速度之间会有一个逐渐加速和逐渐减速的过程。最多选择一个值;如果你不指定任何值(或如果您使用的是简化形式,在没有选择:参数),默认使用UIViewAnimationOptionCurveEaseInOut。你可以选择下面的值之一:

      (1) UIViewAnimationOptionCurveEaseInOut

      (2) UIViewAnimationOptionCurveEaseIn

      (3)UIViewAnimationOptionCurveEaseOut

      (4)UIViewAnimationOptionCurveLinear (constant speed throughout)

    • UIViewAnimationOptionRepeat

      如果包括这个值,动画将无限重复。没有办法可以指定重复一定的数量;你要么永远重复要么不重复。

    • UIViewAnimationOptionAutoreverse

      如果包括的话,动画将从开始运行到终点(在给定持续时间),并且随后将从终点(在给定的持续时间也)运行到开始。按照文档的说法,你只能自动翻转,如果你还重复是不正确的;你可以使用一种或两种(或没有)。

      当使用UIViewAnimationOptionAutoreverse时,你可能会想要在动画终点做一些清理工作,以便在动画结束时,视图回到它的初始位置。为了明白我什么意思,可以看看下面的代码:

      NSUInteger opts = UIViewAnimationOptionAutoreverse; [UIView animateWithDuration:1 delay:0 options:opts animations:^{ CGPoint p = self.v.center; p.x += 100; self.v.center = p; } completion:nil];

    这个视图会以动画形式向右移动100点,然后再移动会原来的位置 --然后就会跳到右边的100点位置。因为我们最后实际赋值给这个视图的center 的x 轴是向右100点,所以但动画结束时,这个“动画电影”被移除时,这个视图仍然在右边100点上。解决方法就是在 completion 处理block中把视图移回它原来的位置:

    CGPoint pOrig = self.v.center;
    NSUInteger opts = UIViewAnimationOptionAutoreverse;
    [UIView animateWithDuration:1 delay:0 options:opts animations:^{
        CGPoint p = self.v.center;
        p.x += 100;
        self.v.center = p;
    } completion:^(BOOL finished) {
        self.v.center = pOrig;
    }];
    

    下面是使用递归链的指定动画次数的方法:

    - (void) animate: (int) count {
        CGPoint pOrig = self.v.center;
        NSUInteger opts = UIViewAnimationOptionAutoreverse;
        [UIView animateWithDuration:1 delay:0 options:opts animations:^{
            CGPoint p = self.v.center;
            p.x += 100;
            self.v.center = p;
        } completion:^(BOOL finished) {
            self.v.center = pOrig;
            if (count)
                [self animate:count-1];
        }]; 
    }
    

    但你传递一个2给这方法来调用,动画会执行3次,然后停止。但这种方式是很危险的,如果数值很大,很容易用完内存。

    还有其他一些选项指定如果另一个动画已经在执行了该怎么做:

    • UIViewAnimationOptionBeginFromCurrentState

      如果这个动画修改的属性同样被一个已经执行的动画修改,这时,不会取消之前的动画,这个动画会使用展示层(presentation layer)来决定从哪里开始执行动画,如果可能,还会混合之前的动画。

    • UIViewAnimationOptionOverrideInheritedDuration

      防止从已经在执行的动画中继承动画的持续时间(默认是继承的)。

    • UIViewAnimationOptionOverrideInheritedCurve

      防止从已经在执行的动画中继承动画曲线(默认是继承的)。

    为了说明 UIViewAnimationOptionBeginFromCurrentState ,考虑下面的代码:

    [UIView animateWithDuration:1 animations:^{
        CGPoint p = self.v.center;
        p.x += 100;
        self.v.center = p;
    }];
    NSUInteger opts = 0;
    [UIView animateWithDuration:1 delay:0 options:opts animations:^{
        CGPoint p = self.v.center;
        p.x = 0;
        self.v.center = p;
    } completion:nil];
    

    结果就是视图跳到右边的100点位置,然后向左边开始动画,移动。 这是因为第二个动画使第一个动画被取消了,向右是瞬间完成,而不是动画。但是,如果我们设定options为UIViewAnimationOptionBeginFromCurrentState,其结果是,该视图的动画从它的当前位置向左执行,并没有跳跃。

    如果我们在第二个动画中把改变x变为改变y,会发生很有趣的事情。如果options为0,那么视图会跳到右边,然后向上移动。如果options为UIViewAnimationOptionBeginFromCurrentState,两个动画会结合起来,视图斜向移动(右上角)。

    为了解析 UIViewAnimationOptionOverrideInheritedDuration,看下面的代码:

    [UIView animateWithDuration:2 animations:^{
        CGPoint p = self.v.center;
        p.x += 100;
        self.v.center = p;
        NSUInteger opts = 0;
        [UIView animateWithDuration:0.5 delay:0 options:opts animations:^{
            self.v.backgroundColor = [UIColor blackColor];
        } completion:nil];
    }];
    

    如果options为0,那么颜色动画的时间跟x轴的动画时间一样,继承了x轴的动画时间。但是如果options为UIViewAnimationOptionOverrideInheritedDuration,每个动画都有自己的执行时间。

    为了停止正在执行的动画,我们可以提供一个冲突的动画,设置视图的位置为最终的位置。

    -(void) animate {
        CGPoint p = self.v.center;
        p.x += 100;
        self.pFinal = p;
        [UIView animateWithDuration:4 animations:^{
            self.v.center = p;
        }];
    }
    -(void) cancel {
        [UIView animateWithDuration:0 animations:^{
            CGPoint p = self.pFinal;
            p.x += 1;
            self.v.center = p;
        } completion:^(BOOL finished) {
            CGPoint p = self.pFinal;
            self.v.center = p;
        }]; 
    }
    

    为了停止一个重复执行的动画,我们可以:

    -(void) animate {
        CGPoint p = self.v.center;
        self.pOrig = p;
        p.x += 100;
        NSUInteger opts = UIViewAnimationOptionAutoreverse |
        UIViewAnimationOptionRepeat;
        [UIView animateWithDuration:1 delay:0 options:opts animations:^{
            self.v.center = p;
        } completion: nil];
    }
    -(void) cancel {
        [UIView animateWithDuration:0 animations:^{
            self.v.center = self.pOrig;
        }];
    }
    

    如果你希望动画的停止不那么突然,可以:

    -(void) cancel {
        NSUInteger opts = UIViewAnimationOptionBeginFromCurrentState;
        [UIView animateWithDuration:0.1 delay:0 options:opts animations:^{
            self.v.center = self.pOrig;
        } completion:nil];
    }
  • 相关阅读:
    iOS内存管理机制
    iOS开发之XML和JSON数据解析
    Ubuntu小点汇总,更新中...
    Android与服务器的简单通讯
    Gedit乱码问题
    Eclipse软件问题-方案积累
    开放接口使用积累
    定制知识积累
    Android小代码-技巧积累
    Android初学点滴积累(操作篇)
  • 原文地址:https://www.cnblogs.com/YungMing/p/4016519.html
Copyright © 2011-2022 走看看