iOS:使用Block而不是CABasicAnimation完成360度旋转

Unh*_*lig 10 core-graphics cabasicanimation uiviewanimation ios

它应该是非常简单的东西,但我还没有成功地使用块来实现它.有这样的问题和答案,但我发现的所有这些都是通过使用CABasicAnimation而不是UIView基于块的动画来解决的,这就是我所追求的.

以下代码不起作用(基于块),没有动画:

CGAffineTransform spin = CGAffineTransformRotate(spiningView.transform, DEGREES_RADIANS(360));

CATransform3D identity = CATransform3DIdentity;
CATransform3D spin2 =  CATransform3DRotate(identity, DEGREES_RADIANS(360), 0.0f, 0.0f, 1.0f);


[UIView animateWithDuration:3.0f
                      delay:0.0f
                    options:UIViewAnimationOptionCurveLinear
                 animations:^
                 {
                     spiningView.transform = spin;
                     //spiningView.layer.transform = spin2;
                     //Have also tried the above, doesn't work either.
                 }
                 completion:^(BOOL finished)
                 {
                     spiningView.transform = spin;
                     //spiningView.layer.transform = spin2;
                 }];
Run Code Online (Sandbox Code Playgroud)

根据我的理解,当我们每次使用Block-Based时,当UIViewAnimationBlock"看到"begin值与最终值相同时,不会发生任何动画.足够公平,将其设置为360度将意味着物体保持原状.但它必须是一种使用基于块的动画来制作动画的方法,因为以下内容CABasicAnimation可以完美地工作:

CABasicAnimation* rotationAnimation;
rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
rotationAnimation.fromValue = [NSNumber numberWithFloat:0.0f];
rotationAnimation.toValue = [NSNumber numberWithFloat: M_PI * 2.0f];
rotationAnimation.duration = 3.0f;
rotationAnimation.cumulative = YES;
rotationAnimation.repeatCount = 1;
[spiningView.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"];  
Run Code Online (Sandbox Code Playgroud)

另外,以下基于块的工作,但在动画之间有一个停止(首先它旋转180度,然后从那里再旋转180度以完成旋转),这不是我所追求的:

[UIView animateWithDuration:3.0f
                      delay:0.0f
                    options:UIViewAnimationOptionCurveLinear
                 animations:^
                 {
                     spiningView.transform = CGAffineTransformRotate(spiningView.transform, DEGREES_RADIANS(180));;
                 }
                 completion:^(BOOL finished)
                 {                         
                     [UIView animateWithDuration:3.0f
                                           delay:0.0f
                                         options:UIViewAnimationOptionCurveLinear
                                      animations:^
                                      {
                                         spiningView.transform = CGAffineTransformRotate(spiningView.transform, DEGREES_RADIANS(360));
                                      }
                                      completion:^(BOOL finished)
                                      {

                                      }];

                 }];
Run Code Online (Sandbox Code Playgroud)

我知道我可以节省很多时间,只是放弃自己使用CABasicAnimation和完成它,但我想知道为什么一个工作而另一个不在这种情况下(进行360度旋转).我希望你能在这个案例中的2和一些可以进行完整360度旋转的代码(基于块)之间给出详细的解释.

提前致谢.

nei*_*lco 28

使用UIView动画,Core Animation计算初始变换和最终变换之间的最短路径.360°旋转不起作用,因为最终变换与初始变换相同.

为了它的价值,我刚刚尝试了以下代码,它可以平滑地进行四次90°旋转,旋转之间没有延迟:

- (void)rotateSpinningView
{
    [UIView animateWithDuration:1.5 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
        [spiningView setTransform:CGAffineTransformRotate(spiningView.transform, M_PI_2)];
    } completion:^(BOOL finished) {
        if (finished && !CGAffineTransformEqualToTransform(spiningView.transform, CGAffineTransformIdentity)) {
            [self rotateSpinningView];
        }
    }];
}
Run Code Online (Sandbox Code Playgroud)

  • 这是一个很酷的解决方案,但为什么四个M_PI_2(90度)旋转而不是两个M_PI(180度)? (2认同)

jaw*_*awj 12

这是iOS 7的关键帧动画非常适合的.例如,您可以将一个完整的旋转view分为三个部分:

CGFloat direction = 1.0f;  // -1.0f to rotate other way
view.transform = CGAffineTransformIdentity;
[UIView animateKeyframesWithDuration:1.0 delay:0.0
                               options:UIViewKeyframeAnimationOptionCalculationModePaced | UIViewAnimationOptionCurveEaseInOut
                            animations:^{
                              [UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.0 animations:^{
                                view.transform = CGAffineTransformMakeRotation(M_PI * 2.0f / 3.0f * direction);
                              }];
                              [UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.0 animations:^{
                                view.transform = CGAffineTransformMakeRotation(M_PI * 4.0f / 3.0f * direction);
                              }];
                              [UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.0 animations:^{
                                view.transform = CGAffineTransformIdentity;
                              }];
                            }
                            completion:^(BOOL finished) {}];
Run Code Online (Sandbox Code Playgroud)

请注意,使用UIViewKeyframeAnimationOptionCalculationModePaced时可以将所有开始时间和持续时间留空.