I want to have a custom transition between two navigation controllers. Let's call the first one sourceController and the other one detailNavController.
Here's my code:
NewEntryViewController *viewController = [[NewEntryViewController alloc]
initWithStyle:UITableViewStyleGrouped];
viewController.parentController = self;
UINavigationController *detailNavController = [[UINavigationController alloc]
initWithRootViewController:viewController];
[UIView beginAnimations:nil context:NULL];
[self.navigationController presentModalViewController:detailNavController animated:NO];
[UIView setAnimationDuration:0.4];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:sourceController.view cache:YES];
[UIView commitAnimations];
SourceController was first presented modally, that's why I'm presenting detailNavController modally. The problem with this code is that the animation takes place, but sourceController is still on top of the new detailNavController. What I would like to achieve is to have the animation and then dismiss sourceController and have detailNavController displayed.
I've finally found the solution for this, here's the updated code:
- (void)createNewEntryWithAnimation
{
// before calling this method I dismissed sourceController without animation
NewEntryViewController *viewController = [[NewEntryViewController alloc] initWithStyle:UITableViewStyleGrouped];
viewController.parentController = self;
UINavigationController *detailNavController = [[UINavigationController alloc]
initWithRootViewController:viewController];
[UIView beginAnimations:nil context:NULL];
[self.navigationController presentModalViewController:detailNavController animated:NO];
[UIView setAnimationDuration:0.4];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:viewController.view.window cache:NO];
[UIView commitAnimations];
}
I had to use cache:NO, otherwise the transition wasn't smooth.
Related
I have TabBarController in my AppDelegate :
IBOutlet TabBarViewController *tab;
This is the main controller in my app.
and in one of the viewcontroller inside the tabs i want to add a UIButton that when the user press it all the tabcontroller will change to another uiviewcontroller with flip animation.
i tried to achive it with this method:
RadioMainVC *radioMainVC = [[RadioMainVC alloc] initWithNibName:#"RadioMainVC" bundle:nil];
UINavigationController *radioNav = [[UINavigationController alloc] initWithRootViewController:radioMainVC];
[UIView beginAnimations:#"animation" context:nil];
[self.tabBarController presentModalViewController:radioNav animated:NO];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.tabBarController.view cache:NO];
[UIView commitAnimations];
And the flip won't work,any idea how to fix it?
Unfortunately I haven't tested this code but it might do the trick:
[UIView transitionFromView: self.tabBarController.view
toView: radioNav.view
duration: 0.5
options: UIViewAnimationTransitionFlipFromLeft
completion: ^(BOOL finished) {
window.rootViewController = radioNav;
}];
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];
I have code:
ListViewController * listViewController = [[ListViewController alloc] initWithNibName:#"ListViewController" bundle:nil];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:YES];
[self viewWillDisappear:YES];
[listViewController viewWillAppear:YES];
self.view.hidden = YES;
listViewController.view.hidden = NO;
[self viewDidDisappear:YES];
[listViewController viewDidAppear:YES];
[UIView commitAnimations];
But it does not works, and listViewController does not displayed( Please, somebody can tell me the solution of this problem?
Try something like:
UIViewAnimationOptions ops = UIViewAnimationOptionTransitionFlipFromRight;
NSArray *temp = [[NSBundle mainBundle] loadNibNamed:#"NameOfNib" owner:self options:nil];
UIView* newView = [[temp objectAtIndex:0] view];
[UIView transitionFromView:self.view toView:newView duration:1.5 options:ops completion:nil];
self.view = newView; //Lets you control the new view from the current controller (you might want to save a reference to the old one if you need to change back)
As meronix said, non-block based animation is discouraged by Apple for the newer iOS versions. The above method is the "approved" way to do it.
Just so you know, the viewWillAppear, viewDidDisappear, and similar methods aren't methods that YOU call to make the view do things. They're called automatically when these things happen.
Your code had a few misunderstandings; I've commented on them below
//This looks fine (depending on what is in the nib)
ListViewController * listViewController = [[ListViewController alloc] initWithNibName:#"ListViewController" bundle:nil];
//Normally I use these to move things around, not change the view
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:YES];
[self viewWillDisappear:YES]; //These two methods aren't things that you call
[listViewController viewWillAppear:YES];
self.view.hidden = YES; //If you're flipping or otherwise moving a view out of
listViewController.view.hidden = NO; //sight then you don't need to hide/unhide views
[self viewDidDisappear:YES]; //Same as above, you don't call these
[listViewController viewDidAppear:YES];
[UIView commitAnimations];
Remove unnecessary code and just write this ...
ListViewController * listViewController = [[ListViewController alloc] initWithNibName:#"ListViewController" bundle:nil];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:YES];
[self.view addSubview:listViewController.view];
[UIView commitAnimations];
it cannot work!
you just create and allocate a UIViewController, but never push it on any stacks, or add its view to a visible view.
when you set listViewController.view.hidden to no, you are not magically showing it on screen: you need to add its view to a view (or window) which is already on screen...
ps beginAnimation is deprecated: use blocks animation instead...
I want to know how to change view on button click in iPhone without navigation controller?
If you're doing this with a UIViewController, you would probably do this like following:
- (IBAction)change {
UIViewController* viewController = [[UIViewController alloc] init];
[self.view addSubView];
// Save the UIViewController somewhere if necessary, otherwise release it
}
Not sure why you don't want to use a UINavigationController though. If it's the navigation bar at the top you don't want to see, there's a property for that so you can hide that bar. Not sure about it's name, probably navigationBarHidden or something like that. You can look that up in the API.
There are many different ways you can do that, and you should possibly provide more information about your app.
A generic way to do it is the following, with animation:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:YES];
[vc1 viewWillDisappear:YES];
[vc2 viewWillAppear:YES];
vc1.view.hidden = YES;
vc2.view.hidden = NO;
[vc1 viewDidDisappear:YES];
[vc2 viewDidAppear:YES];
[UIView commitAnimations];
In this case, both views are there, you only hide/show them as you need. Alternatively, you could add/remove the view from their superview:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:YES];
[vc1 viewWillDisappear:YES];
[vc2 viewWillAppear:YES];
[vc1 removeFromSuperview];
[masterController.view addSubview:vc2.view;
[vc1 viewDidDisappear:YES];
[vc2 viewDidAppear:YES];
[UIView commitAnimations];
Place this in Button IBAction method
[mCurrentView removeFromSuperview];
[self.view addSubView:mNewView];
Assume you have two view myView1 and myView2 and one button myUIButton in memory
myView1.tag = 1;
myView2.tag = 2;
myUIButton.tag = 1; //Current visible view is myView1
-(void) ButtonCLicked:(id) sender
{
UIButton* myButton = (UIButton*)sender;
if(sender.tag == 1)
{
[myView1 removeFromSuperview];
[self addSubview:myView2]
myButton.tag = myView2.tag;
}
else
{
[myView2 removeFromSuperview];
[self addSubview:myView1]
myButton.tag = myView1.tag;
}
}
You can place two UIView variables in the header file and hide/show one of them or you can make another layer over the existing view like this:
-(IBAction)changeView {
UIView *view = [[UIView alloc] initWithNibName:#"letMeSeeThis" bundle:nil];
[self.view addSubview:view];
}
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?