【问题标题】:How to make UIView animation sequence repeat and autoreverse如何使 UIView 动画序列重复和自动反转
【发布时间】:2013-02-06 13:38:04
【问题描述】:

如何让这个复杂的动画重复和自动反转? 有没有办法添加选项 UIViewAnimationOptionAutoreverse | UIViewAnimationOption重复这个动画序列?

   [UIView animateWithDuration:1.0f animations:^{

        someView.frame = someFrame1;

    } completion:^(BOOL finished) {

        [UIView animateWithDuration:0.5f animations:^{

            someView.frame = someFrame2;

        } completion:nil];

    }];

【问题讨论】:

  • 你想使用关键帧动画吗?关键帧动画具有自动反转和自动重复等属性。

标签: ios objective-c uiview uiviewanimation


【解决方案1】:

要从点 1 到 2 到 3 到 2 到 1 动画并重复,您可以在 iOS 7 及更高版本中使用animateKeyframesWithDuration

someView.frame = frame1;
[UIView animateKeyframesWithDuration:2.0 delay:0.0 options:UIViewKeyframeAnimationOptionAutoreverse | UIViewKeyframeAnimationOptionRepeat animations:^{
    [UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.5 animations:^{
        someView.frame = frame2;
    }];
    [UIView addKeyframeWithRelativeStartTime:0.5 relativeDuration:0.5 animations:^{
        someView.frame = frame3;
    }];
} completion:nil];

如果使用自动布局,您可以动画约束常量的变化:

[UIView animateKeyframesWithDuration:2.0 delay:0.0 options:UIViewKeyframeAnimationOptionAutoreverse | UIViewKeyframeAnimationOptionRepeat animations:^{
    [UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.5 animations:^{
        topConstraint.constant = 200;
        leftConstraint.constant = 200;
        [self.view layoutIfNeeded];
    }];
    [UIView addKeyframeWithRelativeStartTime:0.5 relativeDuration:0.5 animations:^{
        topConstraint.constant = 100;
        leftConstraint.constant = 300;
        [self.view layoutIfNeeded];
    }];
} completion:nil];

或者,自动布局的方法是停用约束,然后您可以使用 frame 值或您拥有的值进行动画处理。


在早期版本的 iOS 中,您可以使用 CAKeyframeAnimation,例如沿路径制作动画:

UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(100.0, 100.0)];
[path addLineToPoint:CGPointMake(200.0, 200.0)];
[path addLineToPoint:CGPointMake(100.0, 300.0)];

CAKeyframeAnimation *animatePosition = [CAKeyframeAnimation animationWithKeyPath:@"position"];
animatePosition.path = [path CGPath];
animatePosition.duration = 1.0;
animatePosition.autoreverses = YES;
animatePosition.repeatCount = HUGE_VALF;
[self.someView.layer addAnimation:animatePosition forKey:@"position"];

您可以使用任意数量的点来执行此操作。如果您想沿曲线路径(例如圆形或贝塞尔曲线)制作动画,这也是有用的技术。


如果只是在两点之间做动画,可以使用animateWithDuration:delay:options:animations:completion:,如:

[UIView animateWithDuration:0.5
                      delay:0.0
                    options:UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat | UIViewAnimationOptionCurveEaseInOut
                 animations:^{
                     // do whatever animation you want, e.g.,

                     someView.frame = someFrame1;
                 }
                 completion:NULL];

这将动画someView 从起始帧移动到someFrame1 并返回。

顺便说一句,将UIViewAnimationOptionCurveEaseInOutUIViewAnimationOptionAutoreverseUIViewAnimationOptionRepeat 结合使用会在动画反转和重复时为您提供更平滑的效果。

【讨论】:

  • 在问这个问题之前,我尝试将问题中的 2 个块粘贴到动画块中,并带有选项 Autoreverse 和 Repeat。这不起作用
  • 如何终止以这种方式开始的重复动画,例如当父视图控制器消失时?
  • 一旦视图从视图层次结构中移除,动画会自动停止,您不需要采取进一步的行动(这不像重复计时器或显示链接,您必须自己清理它) .但是,如果您确实想停止重复动画,可以在视图层上调用 removeAllAnimations
  • 为简单起见:我有一个灰色条,我的动画变成蓝色,然后是绿色,文本中带有“Okay”,然后没有文本/回到蓝色,然后是原始灰色。我使用上面的 AutoReverse 以更少的步骤来实现这一点并且它有效。然而,在它反转并最终再次变为灰色后,它会返回到绿色的动画状态,并带有文本“Okay”。为什么要这样做!?为什么它没有在原始的灰色状态下完成?
  • 其实我是新手。我试图在 viewdidload 中加载动画。这就是问题所在。它现在工作。忘记在这里发了。谢谢。
【解决方案2】:

Swift 4 用于简单的摆动序列:

func animateWiggle() {
    // Set animation props
    let scaleDelta = CGFloat(0.10)

    // Set transforms
    let wiggleOutHorizontally = CGAffineTransform(scaleX: 1.0 + scaleDelta, y: 1.0)
    let wiggleOutVertically = CGAffineTransform(scaleX: 1.0, y: 1.0 + scaleDelta)

    // Run animation sequence
    UIView.animateKeyframes(withDuration: 1.0, delay: 0.0, options: [.autoreverse, .repeat], animations: {
        // Animate wiggle horizontally
        UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 0.5, animations: {
            self.transform = wiggleOutHorizontally
        })

        // Animate wiggle vertically
        UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.5, animations: {
            self.transform = wiggleOutVertically
        })
    },
    completion: nil)
}

【讨论】:

    【解决方案3】:
        UIImageView *pin = [UIImageView new];
        [pin setFrame:CGRectMake(115, 160, 30, 60)];
        [pin setBackgroundColor:[UIColor redColor]];
        [holderView addSubview:pin];
    
        [UIView animateWithDuration:1.0 delay:0.0 options:UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat
                         animations:^{
                            // [pin setTransform:CGAffineTransformMakeTranslation(0, 20)];
                             [pin setFrame:CGRectMake(115, 200, 60, 100)];
                         }completion:^(BOOL finished){
    
                         }];
    

    【讨论】:

    • (插入你自己的动画)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-19
    • 2017-11-06
    • 1970-01-01
    • 1970-01-01
    • 2020-02-21
    • 2018-08-31
    相关资源
    最近更新 更多