3

我有一种方法来执行一个小的抖动动画。这个动画有点效果,但每次我从横向位置调用它时它都会旋转。当模拟器处于横向时调用动画时,整个视图会自行旋转为纵向,然后执行动画。旋转本身没有动画,它只是突然变化,没有延迟。视图中的所有内容也会发生变化,所有按钮、文本字段、图像视图等。

动画代码:

- (void)shakeView
{   
    CGFloat t = 8.0;
    CGAffineTransform translateRight = CGAffineTransformTranslate(CGAffineTransformIdentity, 0.0, t);
    CGAffineTransform translateLeft = CGAffineTransformTranslate(CGAffineTransformIdentity, 0.0, -t);

    self.view.transform = translateLeft;

    [UIView animateWithDuration:0.07 delay:0.0 options:UIViewAnimationOptionAutoreverse|UIViewAnimationOptionRepeat animations:^{[UIView setAnimationRepeatCount:3.0];

        self.view.transform = translateRight;
    }
        completion:^(BOOL finished){
        if (finished)
            {
                [UIView animateWithDuration:0.05 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{self.view.transform = CGAffineTransformIdentity;
            }
        completion:NULL];
        }
    }];
}

老实说,我对动画做的不多,所以我不知道我在这里做错了什么,更不用说我应该尝试什么或应该在哪里寻找答案。

我希望在保持动画的同时保持方向。

4

1 回答 1

1

问题是视图已经有一个非身份转换。为了使视图在横向中正确显示,系统会对其应用旋转视图的变换。仅当设备处于 UIDeviceOrientationPortrait 时,视图的变换才为 CGAffineTransformIdentity。此方向旋转仅适用于应用程序的根子视图,即窗口的第一个子视图。当您使用以下命令初始化翻译动画时:

CGAffineTransform translateRight = CGAffineTransformTranslate(CGAffineTransformIdentity, 0.0, t);

您正在告诉旋转视图忽略其旋转并在纵向模式下快速恢复其方向。您可以通过执行以下两项操作之一来解决此问题:

  1. 使动画视图成为根视图的子视图。这样做的好处是系统仍将免费处理旋转,并且您的动画不会搞砸方向更改。此外,代码最终将更简单,更易于维护。

  2. 存储视图的初始转换,并将所有转换应用到它。

我会在这里尝试做#2。

- (void)shakeView
{   
    CGFloat t = 8.0;

    //store the initial transform and use it to create the animated transforms
    CGAffineTransform initialTransform = self.view.transform;
    CGAffineTransform translateRight = CGAffineTransformTranslate(initialTransform, 0.0, t);
    CGAffineTransform translateLeft = CGAffineTransformTranslate(initialTransform, 0.0, -t);

    self.view.transform = translateLeft;

    [UIView animateWithDuration:0.07 
                          delay:0.0 
                        options:UIViewAnimationOptionAutoreverse|UIViewAnimationOptionRepeat 
                     animations:^{
        [UIView setAnimationRepeatCount:3.0];

        self.view.transform = translateRight;
                                }
                     completion:^(BOOL finished){
        if (finished)
        {
            [UIView animateWithDuration:0.05 
                                  delay:0.0 
                                options:UIViewAnimationOptionBeginFromCurrentState 
                             animations:^{
                //restore the initial transform
                self.view.transform = initialTransform;
                                         }
                             completion:NULL];
        }
    }];
}

注意- 从 iOS 8 开始,UIWindow 的根视图不再在旋转时进行变换。相反,UIWindow 本身的边界会发生变化。有关此问题的另一个问题,请参见此处:iOS 8 中的 UIWindow 框架与横向中的 ios 7 不同

于 2013-10-28T14:55:24.463 回答