ios – 如何阻止和反转UIView动画?

前端之家收集整理的这篇文章主要介绍了ios – 如何阻止和反转UIView动画?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我已经动画了一个UIView,当用户触摸切换按钮时它会缩小,并且当用户再次触摸按钮时,它会扩展回原来的大小.到目前为止,一切都很好.问题是动画需要一些时间 – 例如3秒.在此期间,我仍然希望用户能够与界面交互.所以当用户在动画仍在进行的同时触摸按钮时,动画应该停在正确的位置并且反向.

在苹果问答中我已经找到一种方法来暂停所有的动画:

https://developer.apple.com/library/ios/#qa/qa2009/qa1673.html

但我没有看到从这里扭转动画的方法(省略了其余的初始动画).我该如何做到这一点?

- (IBAction)toggleMeter:(id)sender {
    if (self.myView.hidden) {        
        self.myView.hidden = NO;
        [UIView animateWithDuration:3 animations:^{
            self.myView.transform = expandMatrix;
        } completion:nil];
    } else {
        [UIView animateWithDuration:3 animations:^{
            self.myView.transform = shrinkMatrix;
        } completion:^(BOOL finished) {
            self.myView.hidden = YES;
        }];
    }
}

解决方法

除了下面(我们从表示层获取当前状态,停止动画,从保存的表示层重置当前状态,并启动新的动画),有一个更容易的解决方案.

如果要执行基于块的动画,如果要在8.0之前的iOS版本中停止动画并启动新的动画,可以使用UIViewAnimationOptionBeginFromCurrentState选项. (在iOS 8中有效,默认行为不仅是从当前状态开始,而是以反映当前位置以及当前速度的方式执行此操作,从而使其无需担心此问题请参阅WWDC 2014 video Building Interruptible and Responsive Interactions了解更多信息.)

[UIView animateWithDuration:3.0
                      delay:0.0
                    options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionAllowUserInteraction
                 animations:^{
                     // specify the new `frame`,`transform`,etc. here
                 }
                 completion:NULL];

您可以通过停止当前动画并从当前的动画开始新的动画来实现此目的.您可以使用Quartz 2D

> Add QuartzCore.framework to your project如果你还没有(在Xcode的当代版本中,通常不需要明确地这样做,因为它自动链接到项目.)
>如果您还没有(再次,Xcode的当代版本不需要),则导入必要的标题

#import <QuartzCore/QuartzCore.h>

>让你的代码停止现有的动画:

[self.subview.layer removeAllAnimations];

>获取对当前表示层的引用(即视图的状态,正是在此刻):

CALayer *currentLayer = self.subview.layer.presentationLayer;

>根据presentationLayer中的当前值重置变换(或框架或任何内容):

self.subview.layer.transform = currentLayer.transform;

>现在,从该变换(或框架或任何)到新值的动画:

[UIView animateWithDuration:1.0
                      delay:0.0
                    options:UIViewAnimationOptionAllowUserInteraction
                 animations:^{
                     self.subview.layer.transform = newTransform;
                 }
                 completion:NULL];

把这一切都放在一起,这里是一个例程,将我的变换缩放从2.0x切换到识别和返回:

- (IBAction)didTouchUpInsideAnimateButton:(id)sender
{
    CALayer *currentLayer = self.subview.layer.presentationLayer;

    [self.subview.layer removeAllAnimations];

    self.subview.layer.transform = currentLayer.transform;

    CATransform3D newTransform;

    self.large = !self.large;

    if (self.large)
        newTransform = CATransform3DMakeScale(2.0,2.0,1.0);
    else
        newTransform = CATransform3DIdentity;

    [UIView animateWithDuration:1.0
                          delay:0.0
                        options:UIViewAnimationOptionAllowUserInteraction
                     animations:^{
                         self.subview.layer.transform = newTransform;
                     }
                     completion:NULL];
}

或者如果要将帧大小从100×100切换到200×200,然后返回:

- (IBAction)didTouchUpInsideAnimateButton:(id)sender
{
    CALayer *currentLayer = self.subview.layer.presentationLayer;

    [self.subview.layer removeAllAnimations];

    CGRect newFrame = currentLayer.frame;

    self.subview.frame = currentLayer.frame;

    self.large = !self.large;

    if (self.large)
        newFrame.size = CGSizeMake(200.0,200.0);
    else
        newFrame.size = CGSizeMake(100.0,100.0);

    [UIView animateWithDuration:1.0
                          delay:0.0
                        options:UIViewAnimationOptionAllowUserInteraction
                     animations:^{
                         self.subview.frame = newFrame;
                     }
                     completion:NULL];
}

顺便说一句,虽然它对于真正快速的动画来说通常并不重要,但对于像您这样的慢速动画,您可能希望将反转动画的持续时间设置为与您当前动画中进展的距离相同例如,如果你在3.0秒的动画中有0.5秒,当你反转时,你可能不需要花费3.0秒才能扭转你迄今为止所做的一小部分动画,而仅仅是0.5秒).因此,这可能看起来像:

- (IBAction)didTouchUpInsideAnimateButton:(id)sender
{
    CFTimeInterval duration = kAnimationDuration;             // default the duration to some constant
    CFTimeInterval currentMediaTime = CACurrentMediaTime();   // get the current media time
    static CFTimeInterval lastAnimationStart = 0.0;           // media time of last animation (zero the first time)

    // if we prevIoUsly animated,then calculate how far along in the prevIoUs animation we were
    // and we'll use that for the duration of the reversing animation; if larger than
    // kAnimationDuration that means the prior animation was done,so we'll just use
    // kAnimationDuration for the length of this animation

    if (lastAnimationStart)
        duration = MIN(kAnimationDuration,(currentMediaTime - lastAnimationStart));

    // save our media time for future reference (i.e. future invocations of this routine)

    lastAnimationStart = currentMediaTime;

    // if you want the animations to stay relative the same speed if reversing an ongoing
    // reversal,you can backdate the lastAnimationStart to what the lastAnimationStart
    // would have been if it was a full animation; if you don't do this,if you repeatedly
    // reverse a reversal that is still in progress,they'll incrementally speed up.

    if (duration < kAnimationDuration)
        lastAnimationStart -= (kAnimationDuration - duration);

    // grab the state of the layer as it is right now

    CALayer *currentLayer = self.subview.layer.presentationLayer;

    // cancel any animations in progress

    [self.subview.layer removeAllAnimations];

    // set the transform to be as it is now,possibly in the middle of an animation

    self.subview.layer.transform = currentLayer.transform;

    // toggle our flag as to whether we're looking at large view or not

    self.large = !self.large;

    // set the transform based upon the state of the `large` boolean

    CATransform3D newTransform;

    if (self.large)
        newTransform = CATransform3DMakeScale(2.0,1.0);
    else
        newTransform = CATransform3DIdentity;

    // now animate to our new setting

    [UIView animateWithDuration:duration
                          delay:0.0
                        options:UIViewAnimationOptionAllowUserInteraction
                     animations:^{
                         self.subview.layer.transform = newTransform;
                     }
                     completion:NULL];
}

猜你在找的iOS相关文章