I've done a bit of research and read other answers I found here but haven't found anything that actually works. I have an app that when something is posted I want to go to the post and if the back button is pressed when viewing the post it should go back two views basically skip over the compose view.
Below is what I've tried but it gives
Warning: Attempt to present on whose view is not in the window hierarchy!
-(IBAction)post{
[[self presentingViewController] dismissModalViewControllerAnimated:NO];
}
-(void)viewDidDisappear:(BOOL)animated{
[super viewDidDisappear:animated];
ViewPostViewController *dvController = [[ViewPostViewController alloc] initWithNibName:#"ViewPostViewController" bundle:[NSBundle mainBundle]];
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:dvController];
nc.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:nc animated:NO];
[nc release];
}
If you trying to create a hierarchy of views like this, you should probably be using these:
[self.navigationController pushViewController:ViewController animated:BOOL completion:nil];
[self.navigationController popViewControllerAnimated:BOOL completion:nil];
Instead of:
[self presentViewController:ViewController animated:BOOL completion:nil];
[self dimissViewControllerAnimated:BOOL completion:nil];
PresentViewController is usually used to show a single view controller then dismiss it, not generally when you want to show several view controllers in a chain, then work your way back up the chain.
The former is advisable because it uses the stack concept to push and pop view controllers. So you can start with your initial list set up as the root view controller, push on your post compose view, then push on the third view to go to posting. Then when you want to go back to the first view controller by popping off two view controllers, you can use:
[self popToRootViewControllerAnimated:BOOL completion:nil];
You might find the UINavigationController reference useful.
Good luck.
If you want to present a view controller right after another modal view controller has animated out then you have to delay it because otherwise the new one will not appear.
before iOS 5 you would do a performSelectorAfterDelay: with something like 0.25 sec. For iOS 5 and above you wouldn't use modelViewController methods any more as those have been deprecated. Instead you use the presentViewController methods which give you an completion block that is called when the animation is done.
I'm a little confused about what you're trying to do. If you're using a navigation controller, you should be doing pushes and pops, not presenting and dismissing. If you want to use navigation controllers, then you can use popToViewController:animated: to go back to any particular controller without passing through the ones in between. You would have to create a custom back button, though, or do it in code, because the standard back button will only take you back to the previous view controller.
Related
i want to push in another view controller with code
[self pushControllerWithName:#"secondeviewcontroller" context:#"Hello"];
its work great for pushing but for dissmiss
in secondviewcontroller doesn't work
[self dismissController];
In a hierarchical interface, you need to to use [self popController] to go back after pushing a controller.
[self dismissController] is used in modal interfaces.
Currently I have the following code which send the user back to the last active view:
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
After researching presentingViewController I see that is what is causing this view to load. Rather than sending the user to the last active view, I would like to specify the view where they will be redirected. There must be a simple way to adjust this, if so what is it?
It would make much more sense to use a navigation stack for your needs. Instead of presenting this "form" with presentViewController:, embed your view controller within a navigation controller and use:
[self.navigationController pushViewController:theForm animated:YES];
Afterwards, push the next controller onto the stack:
[self.navigationController pushViewController:nextController animated:YES];
I have an app using storyboards and a navigation controller. At some stage in my app flow I get about four views on the view stack at which point I must pop off all the views until I get to the root view. After which I need to manually push another view.
I've tried various things with no luck. I've tried to use the built-in API call:
[self.navigationController popToRootViewControllerAnimated:YES];
At which point I try to call a push segue by referencing the root view and calling the segue method.
RootView *obj = [[RootView alloc] init];
[obj callSegue];
Or
[self.navigationController performSegueWithIdentifier:#"pushView" sender:self];
At any rate, I'm completely stumped on this one. Can anyone help?
UPDATE:
Thanks for the replies everyone. I was digging around some more and found a solution, one of many I'm sure.
// Reference to navigation controller. Apparently if you use self.navigationController in a popToRootViewController call it sets self.navigationController to nil.
UINavigationController *navigationController = self.navigationController;
[navigationController popToRootViewControllerAnimated:NO];
// Reference to view to push - must set storyboard ID in inspector
ViewToPush *viewRef = (ViewToPush *)[self.storyboard instantiateViewControllerWithIdentifier:#"gameView"];
[navigationController pushViewController:gameView animated:NO];
How about this?
[self.navigationController setViewControllers:#[rootViewController, viewControllerTwo] animated:YES];
This sets your stack to your root and a new controller and push animations are used. If you need a quick'n dirty reference for rootViewController, you can use [[self.navigationController viewControllers] objectAtIndex:0].
A good solution to this is to use an "Unwind Segue". Basically, an unwind segue is a segue that takes you back down the stack of pushed controllers, and then performs an IBAction method in the destination controller. What you want to do is make an unwind segue from your current controller to the root, and then put a performSegueWithIdentifier: call in the called method.
Here's a tutorial on unwind segues: Tutorial
Meybe you can try this :
Set a flag (a #property) in your root VC, something like shouldPushAutomatically
In the VC where you call [self.navigationController popToRootViewControllerAnimated:YES];, implement the prepareForSegue:WithIdentifier: method. In this method, use (MyVC*)segue.destinationViewController to access your root VC and set yourflag to YES.
In the viewDidLoad of your root VC, try calling your push segue (in fact, you may need to call it in viewDidAppear).
Not sure if this will work, but that's the way I would try to make it work.
I'm relatively new to iOS development. I am to move from one viewController to another I use a modal segue transition on button click. This is a game so i want to allow the user to click images to essential move the the app menus.
I have a main page that displays several images, on clicking one i want to be able to move to another view. Currently doing this with a modal segue is causing odd problems with my touchesEnded event where if, for example, i navigate to a page 3 times the touchesEnded event is fired 3 times.
Is there a better way for me to do this or am i just missing thing fundamental?
Thanks
Yes, I think you must make the the navigation controller your root view controller then push views accordingly
UINavigationController * nav = [[UINavigationController alloc] initWithRootViewController:YOUR_BASE_CONTROLLER]
self.rootViewController = nav;
this is in your app delegate.
Then in your action method
[self.navigationController pushViewController:secondViewController animated:YES]
Im assuming you are using the Storyboard to link VCs using segues.
Modal segues are great for simple transitions but really seem to limit what you can accomplish when they are just linked through SB. Ive found that creating an IBAction that includes the following for a VC segue will allow you to not only control your segues more efficiently but also allow you to have a clearer view of what is actually occurring during the transition.
-(IBAction)goToVc:(id)sender{
//Other code to take place during the segue here
//This will identify the Storyboard in use
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
//This will identify the View Controller to switch to
SecondViewController *vc2 = [storyboard instantiateViewControllerWithIdentifier:#"SecondViewControllerID" ];
[self presentViewController:vc2 animated:YES completion:NULL];
}
Every time you perform a modal segue, you lose the UINavigationController that you were previously using. What you need to do is embed a UINavigationController in the view that you are performing a modal segue to.
Check out a question I answered the other day to help you visualize more clearly what I'm talking about.
I know there are three ways to change the view in iOS
1.
[self addChildViewController:thirdViewController];
[contentView addSubview:thirdViewController.view];
2.
First * sVC = [[First alloc] initWithNibName:#"First" bundle:[NSBundle mainBundle]];
[self presentModalViewController:sVC animated:YES];
3.
MyViewController *sampleViewController = [[[MyViewController alloc]initWithXXX] autorelease];
[self.navigationController pushViewController: sampleViewController animated:true];
pushViewController requires the navigation controller, which I understand. However, when to use addChildViewController and presentModalViewController??
These are four totally different implementations
addChildViewController is used in iOS5 to do viewController containment, this will enable you to easily create your own NavigationCotrollers or TabControllers its only available in iOS5
addSubview is the lowest level of the three, this will just add a view to another view, as a child
presentModalViewController is used to present a viewController modally on the screen, hence overwriting the old one
pushViewController used in UINavigationController to push a new ViewController to the viewcontrollers stack,
1) was introduced in iOS 5 as part of Apple's paradigm shift to allow view controller hierarchies, it just puts a view controller in front of the current one. You have to manage the flow of controllers.
2) Is the same as one, except it can only be done for one view controller at a time. Actually, this method has been superseded by [self presentViewController:animated:completion:]
3) Adds the view controller to a list so you can go back to the previous one after hitting 'back'. iOS will manage the flow of controllers for you.