如何使UIView动画序列重复并自动反转

41
如何使这个复杂的动画重复并自动反转? 是否有方法将UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat选项添加到此动画序列中?
   [UIView animateWithDuration:1.0f animations:^{

        someView.frame = someFrame1;

    } completion:^(BOOL finished) {

        [UIView animateWithDuration:0.5f animations:^{

            someView.frame = someFrame2;

        } completion:nil];

    }];

你想使用关键帧动画吗?关键帧动画具有自动反向和自动重复的属性。 - Exploring
3个回答

119

要让动画从点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将为您提供更平滑的效果,因为动画会反转和重复。


在提问之前,我尝试将问题中的两个代码块复制到带有自动反转和重复选项的动画块中。但这并没有起作用。 - B.S.
当如何结束一个以这种方式启动的重复动画,例如当父视图控制器消失时? - devios1
2
一旦视图从视图层次结构中移除,动画会自动停止,您无需采取进一步的操作(这不像重复计时器或显示链接,您必须自己清理它)。但是,如果您确实想要停止重复动画,则可以在视图的图层上调用removeAllAnimations - Rob
为了简单起见:我有一个灰色的条形,我的动画会将其变成蓝色,然后是绿色,并带有“好”的文本,然后没有文本/回到蓝色,然后回到原始的灰色。我使用上面的AutoReverse来实现这一点,步骤更少,它起作用了。然而,在它反转并最终再次变成灰色之后,它最终会回到带有文本“好”的绿色动画状态。为什么会这样?为什么它不以最初的灰色状态结束? - Dave G
2
其实我是新手。我试图在viewdidload中加载动画。那就是问题所在。现在它可以工作了。忘记在这里发布了。谢谢。 - Sanjith Bravo Dastan

6

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)
}

-1
    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){

                     }];

(插入您自己的动画) - Johnny Rockex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接