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

B.S*_*.S. 35 objective-c uiview uiviewanimation ios

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

   [UIView animateWithDuration:1.0f animations:^{

        someView.frame = someFrame1;

    } completion:^(BOOL finished) {

        [UIView animateWithDuration:0.5f animations:^{

            someView.frame = someFrame2;

        } completion:nil];

    }];
Run Code Online (Sandbox Code Playgroud)

Rob*_*Rob 109

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

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];
Run Code Online (Sandbox Code Playgroud)

如果使用自动布局,则可以设置约束常量的更改动画:

[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];
Run Code Online (Sandbox Code Playgroud)

或者,自动布局的方法是停用约束,然后您可以使用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"];
Run Code Online (Sandbox Code Playgroud)

你可以用你想要的许多点来做到这一点.如果您想沿弯曲路径(例如圆形或贝塞尔曲线)进行动画制作,这也是一项非常有用的技巧.


要在两点之间进行动画处理,您可以使用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];
Run Code Online (Sandbox Code Playgroud)

这使得someView从起始帧到someFrame1后面的运动变为动画.

顺便说一句,UIViewAnimationOptionCurveEaseInOut与动画一起使用UIViewAnimationOptionAutoreverseUIViewAnimationOptionRepeat在动画反转和重复时给你更平滑的效果.

  • 一旦视图从视图层次结构中移除,动画就会自动停止,您不需要采取进一步的操作(这不像重复计时器或显示链接,您必须自己清理它)。但是,如果您确实想停止重复动画,则可以在视图层上调用“removeAllAnimations”。 (2认同)
  • 其实我是新手。我试图在viewdidload中加载动画。那就是问题所在。现在正在工作。忘了在这里发布。谢谢。 (2认同)

Cra*_*lot 5

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)
}
Run Code Online (Sandbox Code Playgroud)