我有一个应用程序,它有一个带有开始按钮的开始屏幕。如果点击该按钮,视图会发生变化并显示新视图,让我们调用该主视图。
我实现它的方式是每个视图一个视图控制器。现在我想添加过渡动画,这种实现会导致问题。例如,我想使用以下代码:
[UIView transitionFromView:startView toView: mainView duration: 2.0
options: UIViewAnimationOptionTransitionCurlDown completion: NULL];
但这没有做任何事情。阅读文档表明,这仅在视图控制器不更改时才有效。该文档没有任何关于视图控制器发生变化的卷曲过渡的例子,所以我不知道该怎么做。
当我开始编写应用程序时,我阅读了指南,他们建议每个视图使用一个视图控制器是正确的做法。
现在,当视图控制器发生变化时,实现视图转换的正确方法是什么?非常感谢你的帮助!
编辑:我正在寻找第一个视图控制器被销毁的解决方案。
答案 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 !!