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];
    }
  • 相关阅读:
    49. 字母异位词分组
    73. 矩阵置零
    Razor语法问题(foreach里面嵌套if)
    多线程问题
    Get json formatted string from web by sending HttpWebRequest and then deserialize it to get needed data
    How to execute tons of tasks parallelly with TPL method?
    How to sort the dictionary by the value field
    How to customize the console applicaton
    What is the difference for delete/truncate/drop
    How to call C/C++ sytle function from C# solution?
  • 原文地址:https://www.cnblogs.com/YungMing/p/4016519.html
Copyright © 2011-2022 走看看