如何实现UIView转换

时间:2011-04-24 20:45:45

标签: iphone ios architecture uiview

我有一个应用程序,它有一个带有开始按钮的开始屏幕。如果点击该按钮,视图会发生变化并显示新视图,让我们调用该主视图。

我实现它的方式是每个视图一个视图控制器。现在我想添加过渡动画,这种实现会导致问题。例如,我想使用以下代码:

[UIView transitionFromView:startView toView: mainView duration: 2.0 
 options: UIViewAnimationOptionTransitionCurlDown completion: NULL];

但这没有做任何事情。阅读文档表明,这仅在视图控制器不更改时才有效。该文档没有任何关于视图控制器发生变化的卷曲过渡的例子,所以我不知道该怎么做。

当我开始编写应用程序时,我阅读了指南,他们建议每个视图使用一个视图控制器是正确的做法。

现在,当视图控制器发生变化时,实现视图转换的正确方法是什么?非常感谢你的帮助!

编辑:我正在寻找第一个视图控制器被销毁的解决方案。

3 个答案:

答案 0 :(得分:2)

有人建议你有效地创建一个视图控制器,使用它的视图,但是忽略控制器本身。不建议这样做。在iOS中,您希望使视图控制器层次结构与视图层次结构保持同步。因此,所提出的任何技术都是有问题的。 (WWDC 2011 session 102,在不同的主题上,查看控制器包含,对长时间讨论保持这两个层次结构同步的重要性。)

最明显的问题是某些事件,尤其是旋转事件,不会成功传输到新控制器,您可能会得到一些非常奇怪的结果。你的代码也不清楚你所删除的旧视图,你将如何转换回来,如何清理现在不必要的游戏控制器,如果你在didReceiveMemoryWarning会发生什么游戏控制器等等。这似乎引入了一大堆问题。

最简单的解决方案是应用标准pushViewController和/或presentViewController调用,从一个视图转到另一个视图,并为这些转换设置动画。如果您对这些方法中的任何一个有疑问,或者如何在这些方法的上下文中制作动画,请告诉我。

答案 1 :(得分:2)

顺便提一下,问题的根源是如何在视图控制器之间进行转换。这是我曾经玩过的旧过渡集合(一些用于推动过渡,一些用于模态过渡)。也许你可以使用这里的东西?

- (void)transitionToNewController
{
    MyViewController *controller = [[MyViewController alloc] initWithNibName:@"MyView" bundle:nil];

#if TRANSITIONTYPE == 1

    // pushViewController with push/slide from right via CATransition

    CATransition* transition = [CATransition animation];

    transition.duration = 0.3;
    transition.type = kCATransitionPush;
    transition.subtype = kCATransitionFromRight;

    [self.navigationController.view.layer addAnimation:transition forKey:kCATransition];
    [self.navigationController pushViewController:controller animated:NO];
#endif

#if TRANSITIONTYPE == 2

    // pushViewController with flip using UIView begin/commitAnimations

    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
    [UIView setAnimationDuration:0.75];
    [self.navigationController pushViewController:controller animated:NO];
    [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.navigationController.view cache:NO];
    [UIView commitAnimations];
#endif

#if TRANSITIONTYPE == 3

    // pushViewController with flip using animation block

    [UIView animateWithDuration:0.5 
                     animations:^{
                         [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
                         [self.navigationController pushViewController:controller animated:NO];
                         [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.navigationController.view cache:NO];
                     }
                     completion:nil];

#endif

#if TRANSITIONTYPE == 4

    // pushViewController with fade via CATransition

    CATransition* transition = [CATransition animation];

    transition.duration = 0.5;
    transition.type = kCATransitionFade;

    [self.navigationController.view.layer addAnimation:transition forKey:kCATransition];
    [self.navigationController pushViewController:controller animated:NO];
#endif

#if TRANSITIONTYPE == 5

    // pushViewController with fade via animation block

    controller.view.alpha = 0.0f;

    [UIView animateWithDuration:0.5 
                     animations:^{
                         self.view.alpha = 0.0f;
                         controller.view.alpha = 1.0f;
                     }
                     completion:^(BOOL finished){
                         [self.navigationController pushViewController:controller animated:NO];
                         self.view.alpha = 1.0f; // reset the src alpha so it's there when you pop your view controller off
                     }];
#endif

#if TRANSITIONTYPE == 6

    // pushViewController Flip using UIView begin/commitAnimations

    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
    [UIView setAnimationDuration:0.75];
    [self.navigationController pushViewController:controller animated:NO];
    [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:[self.self navigationController].view cache:NO];
    [UIView commitAnimations];
#endif

#if TRANSITIONTYPE == 7

    // pushViewController animation using CGAffine scale to look like we're zooming into the new view

    [self.view addSubview:controller.view];
    [controller.view setFrame:self.view.window.frame];
    [controller.view setTransform:CGAffineTransformMakeScale(0.5,0.5)];
    [controller.view setAlpha:1.0];

    [UIView animateWithDuration:0.5
                          delay:0.0
                        options:UIViewAnimationCurveEaseOut 
                     animations:^{
                         [controller.view setTransform:CGAffineTransformMakeScale(1.0,1.0)];
                         [controller.view setAlpha:1.0];
                     } 
                     completion:^(BOOL finished){
                         [controller.view removeFromSuperview];
                         [self.navigationController pushViewController:controller animated:NO];
                     }];
#endif

#if TRANSITIONTYPE == 8

    // presentViewController animation with slide from right by using CGAffineTransform

    self.view.transform = CGAffineTransformMakeTranslation(0, 0);
    controller.view.transform = CGAffineTransformMakeTranslation(self.view.frame.size.width, 0);
    [self.view addSubview:controller.view];

    [UIView animateWithDuration:4.0
                     animations:^{
                         //                         [self presentViewController:controller animated:NO completion:nil];
                         self.view.transform = CGAffineTransformMakeTranslation(self.view.frame.size.width, 0);
                         controller.view.transform = CGAffineTransformMakeTranslation(0, 0);
                     }
                     completion:^(BOOL finished){
                         [controller.view removeFromSuperview];
                         [self presentViewController:controller animated:NO completion:nil];
                     }
     ];
#endif

#if TRANSITIONTYPE == 9

    // presentViewController animation with slide from right by just animating frames

    float width = self.navigationController.view.frame.size.width;

    CGPoint right = controller.view.center;
    right.x += width;
    controller.view.center = right;

    [self.navigationController.view addSubview:controller.view];

    [UIView animateWithDuration:0.5
                     animations:^{
                         CGPoint left = self.navigationController.view.center;
                         left.x -= width;
                         self.navigationController.view.center = left;
                     }
                     completion:^(BOOL finished){
                         [controller.view removeFromSuperview];
                         [self presentViewController:controller animated:NO completion:nil];
                     }
     ];
#endif

#if TRANSITIONTYPE == 10

    // presentViewController animation with flipfromright

    [UIView animateWithDuration:4.0
                          delay:0.0 
                        options:UIViewAnimationOptionTransitionFlipFromRight 
                     animations:^{
                         [self.view addSubview:controller.view];
                     }
                     completion:^(BOOL finished){
                         [controller.view removeFromSuperview];
                         [self presentViewController:controller animated:NO completion:nil];
                     }];
#endif

#if TRANSITIONTYPE == 11

    // presentViewController with flip using UIView begin/commitAnimations

    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
    [UIView setAnimationDuration:0.75];
    [self presentViewController:controller animated:NO completion:nil];
    [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:NO];
    [UIView commitAnimations];
#endif

#if TRANSITIONTYPE == 13

    // pushViewController with flip using animation block with transitionWithView

    controller.view.frame = self.view.window.frame;

    [UIView transitionWithView:self.view.superview 
                      duration:1.0
                       options:UIViewAnimationTransitionFlipFromRight
                    animations:^{
                        [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
                        [self.view.superview addSubview:controller.view];
                        [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.navigationController.view cache:NO];
                    }
                    completion:^(BOOL finished){
                        [self.navigationController pushViewController:controller
                                                             animated:NO];
                    }];

#endif

}

答案 2 :(得分:1)

Okey-doke,我找到了一种巧妙的方法来实现我想要的。这个代码添加在我交换旧视图控制器和查看新方法的方法中,效果很好:

GameViewController *game = [[GameViewController alloc] init];
UIView *currentView = [currentViewController view];
// remove the current view and replace with myView1
[currentView removeFromSuperview];
// set up an animation for the transition between the views
CATransition *animation = [CATransition animation];
[animation setDuration:0.5];
[animation setType:kCATransitionPush];
[animation setSubtype:kCATransitionFromBottom];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; 
[[window layer] addAnimation:animation forKey:@"SwitchToView1"];    
[self setCurrentViewController: game];
[window addSubview:[currentViewController view]];
[game release];

非常感谢HERE !!