iPhone横屏模式下使用UIViewAnimationTransitionFlipFromLeft实现翻转动画

13

我正在开发一个 iPhone 应用程序,其中实现了一个动画 UIViewAnimationTransitionFlipFromLeft。在应用程序中,当处于竖屏模式时,它按照指定的方式执行相同的从左向右翻转动画。

但是,当我在横屏模式下使用 UIViewAnimationTransitionFlipFromLeft 时,它不会从左到右旋转,而是从上到下旋转。这真的是一个很棘手的问题。你能帮我解决吗?

我在 iPhone 应用程序中使用的代码如下:

   CGContextRef context = UIGraphicsGetCurrentContext();
    [UIView beginAnimations:nil context:context];
    [UIView setAnimationTransition: UIViewAnimationTransitionFlipFromLeft forView:self.view.window cache:NO];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
    [UIView setAnimationDuration:1.0];
    [UIView commitAnimations];
    [self.navigationController pushViewController:objSecond animated:YES];

感谢您的支持, 最好的问候, Gurpritsingh Saini


你确定你的应用程序支持横向模式吗?根据你所描述的,似乎你的应用程序在肖像模式下执行FlipFromLeft操作,无论你如何握住设备(横向或纵向)。 - Swapnil Luktuke
你好,我的应用程序支持 iPhone 上可用的所有四个方向。在纵向模式下,从左到右的翻转动画运行良好。但是在横向模式下,它会从上到下翻转,而不是从左到右。你能帮我解决这个问题吗? - AppAspect
你能重新格式化你的代码吗?为什么要这样做...self.view.window.transform = CGAffineTransformMakeRotation(M_PI * 0.50) - ax123man
哦,抱歉,那是我的失误。我只是在测试这个,但它没有起作用。你能帮我吗?我非常需要它。 - AppAspect
一个要点:在你上面的代码中,你正在使用旧的UIView方法beginAnimations:context:。context参数不是CGContextRef。它是一个键,用于跟踪哪个动画是哪个。它应该是一个NSString。我希望传递一个CGContextRef会导致编译器警告,并且可能会导致内存管理问题,因为CGContextRef是一个Core Foundation对象,而不是NSObject。 - Duncan C
5个回答

15

如果你使用的是 iOS 4.0 或之后的版本,以下代码将完全符合你的需求(我刚测试了一下以确认)

NewView *myNewView = [[NewView alloc] initWith.....];
[UIView transitionFromView:self.view toView:myNewView.view duration:1 options:UIViewAnimationOptionTransitionFlipFromLeft completion:nil];
//[self.navigationController pushViewController:myNewView animated:NO];
[myNewView release];

编辑:我稍微改动了上面的代码(没有新内容,只是注释掉导航控制器,因为这对于此操作不必要)。

所以有几种方法可以实现这一点(跟踪下一个视图),但这是我能想到的最简单的方法。您已经可以从视图1切换到视图2,所以我将解释如何从2转到10(或任何您需要的数量)。

基本上,视图过渡时间太长,viewDidLoad 无法捕捉到调用进入下一个视图的方法。因此,我们需要设置一个计时器,等待并发送一个方法在稍后切换。因此,这是您将在视图2(以及3和4等)中看到的代码。

- (void)viewDidLoad {
    // this gets called before animation finishes, so wait;
    self.navigationController.delegate = self;
    // you will need to set the delegate so it can take control of the views to swap them;
    [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(switchView) userInfo:nil repeats:NO];
}

我只等待1秒钟,然后调用switch方法,但如果你在视图中加载了很多东西,你可能需要等待更长的时间。1.5秒应该足够了,但你可以试试看哪里起作用,哪里不起作用。

接下来,在switchView方法中你必须调用下一个视图。

- (void)switchView {
    NextView *myNextView = [[NextView alloc] initWith ... ];
    [UIView transitionFromView:self.view toView:nextView.view duration:1 options:UIViewAnimationOptionTransitionFlipFromLeft completion:nil];
    [nextView release];
}

这对我来说完美地工作了。为了确保我获得了新的视图,我为每个视图分配了标签,并在每个视图的viewDidLoad方法中添加了UILabel作为其子视图,每个Label都显示了其视图的数量。所以希望这就是你需要的。我相信你还有更复杂的事情要做,但这将为您提供所需的动画和逻辑,以获得您想要的外观。(顺便说一句,当这样做时,viewDidAppear似乎不会被调用,因此如果您真的需要使用它,则可能需要从viewDidLoad手动调用它,但除此之外它可以正常工作)


你好Slev,感谢您在这里发布答案。它真的很有帮助。但是在“pushViewController”之外,我还需要从下一个控制器执行“Popviewcontroller”,我尝试过了,但现在不起作用。并且在这里,只有当我将一个视图推到另一个视图时才有效。但在我的应用程序中,我有两个控制器的层次结构,直到第n级。因此,使用此方法无法在第二个视图控制器之后进行操作。 - AppAspect
我认为我可能有一个可能的解决方案,尽管我将编辑我的原始答案并添加一些内容,以便更容易阅读(以及输入)。 - justin
你好Slev,我检查了这段代码,但在我的电脑上无法运行。你能给我一些可用的参考资料吗? - AppAspect
哪一部分对你来说不起作用?这样我就可以尝试提供更适合你需求的代码。我之所以这么说是因为我上面的代码对我来说是有效的(无论是前往还是返回视图),所以如果你能让我知道哪一部分不起作用(或者你需要做什么),我将非常乐意帮助。 - justin
那就是我需要知道的全部内容。我已经设置好了一个练习应用程序可以进行工作,所以当我找到问题时会再联系您的。希望不需要太长时间,因为我已经有几个想法了。 - justin
显示剩余9条评论

2

您需要手动为视图添加转换;翻转变换始终会像视图控制器处于纵向方向一样操作。

请注意,+beginAnimations:context: 的上下文参数并不是指 CGContextRef。您可能不想在此处传递当前的图形上下文,请改为传递 NULL


你好,我已经移除了当前的图形上下文并将其设置为NULL,但是仍然出现了之前的问题。它在纵向模式下工作正常,但在从左到右的横向模式下不起作用,这是我们的要求。请问你能帮我解决这个问题吗? - AppAspect
你说的转换参考资料是什么? - AppAspect

1
CGContextRef context = UIGraphicsGetCurrentContext();

[UIView beginAnimations:nil context:context];

[UIView setAnimationTransition: UIViewAnimationTransitionFlipFromLeft forView:self.view cache:NO];

[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];

[UIView setAnimationDuration:1.0];

[UIView commitAnimations];

我认为这会行得通。


请注意 - 缩进4个空格(或使用{}按钮)来格式化代码 - 更多帮助请参阅此处 - McDowell
你好,它不起作用,顺便说一下,这是我在这里发布的相同代码。你能否提供你所拥有的完美解决方案。提前致谢。 - AppAspect

1
尝试使用这个:

CABasicAnimation *rotateAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
    CGFloat startValue = 0.0;
    CGFloat endValue = M_PI;
    rotateAnimation.fromValue = [NSNumber numberWithDouble:startValue];
    rotateAnimation.toValue = [NSNumber numberWithDouble:endValue];
    rotateAnimation.duration = 1.5;
    [self.view.layer addAnimation:rotateAnimation forKey:@"rotate"];

0

slev的被接受的答案对我没有用,我在我的自定义Segue中尝试代码后遇到了各种错误。我找到了一种方法,不仅有效而且更精确,因为它不需要使用计时器。这是我的MySegue.m:

@implementation FlipRightSegue

- (id)initWithIdentifier:(NSString *)iden source:(UIViewController *)sour destination:(UIViewController *)dest
{
    self = [super initWithIdentifier:iden source:sour destination:dest];

    return self;
}

- (void)perform
{

    UIViewController *src = [self sourceViewController];
    UIViewController *dst = [self destinationViewController];

    //[UIView transitionFromView:src.view toView:dst.view duration:1 options:UIViewAnimationOptionTransitionFlipFromRight completion:nil];
    //[UIView commitAnimations];

    [UIView transitionWithView:src.navigationController.view duration:0.8 options:UIViewAnimationOptionTransitionFlipFromLeft
                   animations:^{
                       [src.navigationController pushViewController:dst animated:NO];
                   }
                   completion:NULL];
}

@end

我还有一个向右翻转的第二个类。代码取自这个网站:http://www.dailycode.info/Blog/post/2012/11/29/iOS-Custom-Flip-Segue-(portrait-and-landscape-layout)-xcode-4.aspx


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