How do i do a flip animation on pop view controller? - iphone

I have a flip animation which goes like this:
Picker *picker = [[Picker alloc] init];
[self.navigationController pushViewController:picker animated:NO];
[UIView animateWithDuration:0.5
animations:^{
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.navigationController.view cache:NO];
}
completion:^(BOOL finished){
}];
[picker release];
This works perfectly. But when i want to do popViewController to get back, like this:
[self.navigationController popViewControllerAnimated:NO];
[UIView animateWithDuration:0.5
animations:^{
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.navigationController.view cache:NO];
}
completion:^(BOOL finished){
}];
But this doesn't work, just goes back to the view without animating.

Have you tried calling popViewControllerAnimated after the animation ends?

Put the popViewController call inside your completion block, so it animates first and then pops.

Related

pushViewController without title animation

I push Viewcontroller using this code:
if (! self.infoViewController) {
self.infoViewController = [[InfoViewController alloc] initWithNibName:#"InfoViewController" bundle:nil];
}
[UIView animateWithDuration:0.7f
animations:^{
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[self.navigationController pushViewController:self.infoViewController animated:NO];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.navigationController.view cache:NO];
}];
Is it possible to disable navigationBar title animation? It's slide from left during animation.
Push your ViewController without animation like this:
if (! self.infoViewController) {
self.infoViewController = [[InfoViewController alloc] initWithNibName:#"InfoViewController" bundle:nil];
}
[self.navigationController pushViewController:self.infoViewController animated:NO];
this will not animate ur pushing title. I hope this will helps u.
I'm sorry. Here is the answer:
[UIView animateWithDuration:0.7f
animations:^{
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.navigationController.view cache:NO];
}];
[self.navigationController pushViewController:self.infoViewController animated:NO];

iphone dev: how to control the view transition animation?

I am using such code to present a new view, I don't it's good or not. Currently the default animation is show the view from bottom up, but i want it to animate from right to left(fly in), is it possible to change the default animation type and how? Thanks.
[self presentModalViewController:navController animated:animated];
You can disable the slide-up animation like this:
[self presentModalViewController:navController animated:NO];
Then you can provide your own animation code:
navController.view.frame = CGRectMake(320, 0, navController.view.frame.size.width, navController.view.frame.size.height);
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
navController.view.frame = CGRectMake(0, 0, navController.view.frame.size.width, navController.view.frame.size.height);
[UIView commitAnimations];
This example gives you the "Fly-in" from right with a smooth speed-curve.
Another way is using the built in slide-in from right with navigationcontroller:
[self.navigationController pushViewController:navController animated:YES];
In this one, your top-viewcontroller needs to be a UINavigationController and it's rootcontroller needs to be your viewcontroller. Then you can push other viewcontrollers.
I have done this and its working for me try ths:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.6];
[UIView setAnimationDelegate:self];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.View2.superview cache:YES];
[self.View2 removeFromSuperview];
[self performSelector:#selector(replaceViews2) withObject:nil afterDelay:0.6];
[UIView commitAnimations];

Why do I see jerky animation when using this UIView animation block?

I have a a tab bar that is made in the application delegate. By calling an action form a button click from one of the views loaded from the tab bar, I open the help screen but there is a jerking motion after loading.
forgive me for speaking informally..I have been picking my brain for the past few hours trying to figure this out..
-(void)flipToHelp {
HelpViewController *helpVariable = [[HelpViewController alloc] initWithNibName:#"HelpView" bundle:nil];
[self setHelpViewController:helpVariable];
[UIView beginAnimations:#"flipview" context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft
forView:_window cache:YES];
[_window removeFromSuperview];
[helpVariable release];
self.window.rootViewController = self.HelpViewController;
[UIView commitAnimations];
}
Just to reiterate from the comment thread, you shouldn't be removing the window from its superview (it doesn't technically have a superview, so it's probably causing problems). And setting the window's rootViewController property should swap out the view hierarchies, Apparently the jerkiness comes from changing the window's rootViewController property, so maybe the solution is to avoid using that property. Here's what I think should be enough to accomplish this:
-(void)flipToHelp {
HelpViewController *helpVariable = [[HelpViewController alloc] initWithNibName:#"HelpView" bundle:nil];
[UIView beginAnimations:#"flipview" context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:_window cache:YES];
[self.tabBarController removeFromSuperview];
[_window addSubview:helpVariable];
[UIView commitAnimations];
}
-(void)flipToHelp {
HelpViewController *helpVariable = [[HelpViewController alloc] initWithNibName:#"HelpView" bundle:nil];
[self setHelpViewController:helpVariable];
[helpVariable release];
[UIView beginAnimations:#"flipview" context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft
forView:self.window
cache:YES];
self.window.rootViewController = self.HelpViewController;
[UIView commitAnimations];
}
How about this code? Does it still have a jerky animation?

How to implement UIView transition

I have an app which has a start screen with a start button on it. If you tap that button the view changes and a new view appears, let's call that main view.
The way I implemented it is one view controller per view. Now that I want to add transition animations this implementation causes problems. For example, I want to use the following code:
[UIView transitionFromView:startView toView: mainView duration: 2.0
options: UIViewAnimationOptionTransitionCurlDown completion: NULL];
But this doesn't do anything. Reading the documentation suggests that this only works if the view controller doesn't change. The documentation doesn't have any examples of a curl down transition where the view controllers change so I'm not sure what to do.
When I started writing the app I read the guidelines and they suggested that having one view controller per view is the correct way of doing what I'm doing.
Now what is the correct way to implement a view transition when the view controller changes too? Many thanks for your help!
Edit: I am looking for a solution where the first view controller is destroyed.
It was proposed that you effectively create a view controller, use its view, but then disregard the controller itself. This is not advised. In iOS you want to keep your view controller hierarchy synchronized with your view hierarchy. Any techniques like the one proposed are therefore problematic. (WWDC 2011 session 102, while on a different topic, view controller containment, has a lengthy discussion of the importance of keeping these two hierarchies synchronized.)
The most obvious problem is that certain events, notably rotation events, are not going to transmitted successfully to your new controller and you can get some very strange results. It's also not clear with your code above what happens with the old view that you removed, how you would transition back, how you'd clean up the now unnecessary game controller, what would happen on didReceiveMemoryWarning if you were in the game controller, etc. This just seems to introduce a ton a problems.
The easiest solution is apply standard pushViewController and/or presentViewController calls to go from one view to another, and just animate those transitions. If you have questions about either of those methods, or how to animate within the context of those methods, let me know.
By the way, the root of your question was how to transition between view controllers. Here is a old collection of transitions (some for push transitions, some for modal transition) that I was once playing around with. Maybe there's something here that you could use?
- (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
}
Okey-doke, I found a neat way to achieve exactly what I want. This code, added in the method where I exchange the old view controller and view with the new one, works great:
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];
Many thanks to HERE!!

presentModalViewController gives error?

if i run following gives error,current controller is table controller....
SetController *aSecondView = [[SetController alloc] initWithNibName:#"Sets" bundle:nil];
SchedAppDelegate *mainDelegate = (SchedAppDelegate *)[[UIApplication sharedApplication] delegate];
[mainDelegate setSettingsViewController:aSecondView];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:2.0];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:[[self view] superview] cache:YES];
[self.view removeFromSuperview];
[self presentModalViewController:aSecondView animated:NO];
//[aSecondView release];
[UIView commitAnimations];
It appears that mView is a UIViewController and not a UIView.
This is the proper way to apply a custom animation to a modal view controller:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:2.0];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:[self view] cache:YES];
[self presentModalViewController:mView animated:NO];
[UIView commitAnimations];
If mView is a view controller, you can present it with a flip animation by doing the following:
mView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:mView animated:YES];
The modalTransitionStyle property is only available for iPhone OS 3.0 onwards. Hope this helps. :)