performSegueWithIdentifier and popViewControllerAnimated breaking screen navigation - iphone

I have 4 ViewControllers A, B, C, D. I move from A->B->C->D using Push Segues created from Storyboard.
Due to the logic of my app, if the user wants to go back from Screen D, screen C is no longer valid and I redirect the user to Screen C by using performSegueWithIdentifier
The problem starts now - I can't move back from Screen B->A using [self.navigationController popViewControllerAnimated:YES];
I would like to know why is this happening and how can I address such a scenario & fix the navigation?

What is the type of segue that you use?
Why don't you use:
- (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated
You can access the stack of view controllers using the viewControllers property of UINavigationController.
Here is Apple's documentation on UINavigationController

Related

Dismissing 3 layers of modal view

In my application, I have three layers of modal view controllers.
1) So my rootViewController is a tabbar.
2) On applicationDidFinishLaunching I am presenting a viewController, say viewController A modally above tabbar.
3) On click of a button in 'viewController A', I present another viewController B modally.
4) And a button action on viewController B presents navigationController modally with its rootViewController as viewController C.
5) Finally from viewController C, I want to go back to viewController A.
I tried using
[[[self parentViewController] parentViewController]dismissModalViewControllerAnimated:YES];
in viewController C, but it reverts me back to viewController B instead of viewController A.
How can I revert back to viewController A.
Any help would be appreciated.
push all the 'modal' views on a navigationControl with a transitionStyle that looks like the modalTransitionStyle..dont reinvent stuff
present all in one modal navigationController Id say :)
You've got a complex VC stack. You could as one poster suggested implement a custom dismissView method, but that would be fragile: if you reuse this view, or move it in your app, it will cease functioning, because it relies too much on specific knowledge of how other VCs have configured their state.
You could configure a delegation chain. This would be the standard way to manipulate views: the presenting VC is also responsible for removing anything it presents.
To do so, build a protocol implemented by B, and initialize C with a reference to B. Similarly, initialize B with a reference to A (with potentially the same protocol, depending on any other communication that needs to be passed between them.)
Then when the button is clicked on C, it calls B's delegate method. B unwinds C as appropriate, and calls A's delegate method. A unwinds B as appropriate.
This has the advantage of keeping VC knowledge encapsulated: A knows how it presented B, so it knows how to unpresent it, and B knows how it presented C, and knows how to un-present it. In no case does one VC need to make assumptions about how it was presented by another.
Implement the view dismissing method like:
- (IBAction)dismissView
{
[self dismissModalViewControllerAnimated:NO]; // dismiss c
[[self parentViewController] dismissModalViewControllerAnimated:NO]; //dismiss b
}
[self parentViewController] will return the parent view of viewControllerC, that's viewControllerB. So it'll dismiss that view too.

iOS - strangeness in the navigationController

I have createa an app that is based on "Single View Application" Xcode template. It has a navigation controller and a rootViewController.
When I am on the rootViewController and I do
[self presentModalViewController:nextModalViewController animated:YES];
the new view controller is animated in.
My problem is this. I have presented a lot of viewControllers in sequence, that is
A > B > C > D
or in other words, I have presented B from A using presentModalViewController, C from B and so one. Yes, I have to use presentModalViewController because I have a special animation going on to transition between viewControllers and I cannot use [self.navigationController push...
My question is: what happens when I use presentModalViewController regarding to the navigation stack? Is the controller being presented pushed to some stack? is there a way to obtain references to all navigationControllers that were presented at a given time? something like that navigation stack? I mean, suppose I am on D and I want to get a list of all controllers presented before D.
I know I can create properties and pass that along. I am just wondering if theres something already built on iOS that does that.
thanks.
In iOS 5 and later, UIViewController has a presentingViewController property that returns the view controller that presents the receiver. In iOS 4 and earlier, use the parentViewController property of the presented view controller to access its presenting view controller. So you can access, for example, the C view controller from D by accessing these properties appropriately. See the docs for further information.
If you want to access all the view controllers as in a chain, you can do this:
UIViewController *node = self;
while (node != nil) {
// do something with the view controller, then skip to its parent
node = node.presentingViewController;
// or node = node.parentViewController; in iOS 4 or older
}
I'd subsequently check the size of the viewControllers property from your UINavigationController after every modal presentation, and check if it grows or not.
UIViewController *theControllerYouWant = [self.navigationController.viewControllers objectAtIndex:(theIndexOfYourViewController)];

iOS 5 return to initial nib view resembling a sign out button

this if my first post so please be gentle.
I have an iOS 5 app (using storyboards) where I want the user to have the ability to sign out, and with that reset all settings in the app, and also return the user to the very first nib view.
I have already used this code:
[self.navigationController popViewControllerAnimated:YES];
and the problem with this is that it only sends the user back 1 view and not several.
The issue with this is that I have multiple table views that derive from each other and I want the Sign Out button to remain visible in every single one of these detailed views.
Also, this has to work on both iPhone and iPad (Universal)
Any suggestions?
Thanx.
Why not assign a BOOL value YES on button click, then in the viewWillAppear of each viewController:
(assuming BOOL signingOut)
if(signingOut){ [self.navigationController popViewControllerAnimated:YES]; }
Otherwise, just use:
[self.navigationController popToRootViewControllerAnimated:NO];
Why not set the viewControllers array on the navigation controller.
Or send your logout command to the root controller of the navigation controller and have it pop the navigation controller without animation until there are two left. Then pop the second to last one animated. Then you should still get the navigation animation

Making a UINavigationController go back via code

The UINavbarcontroller will go back to the previous VC when i press the Left button on the NavBar. Works as expected.
I also need to force the screen to go back from another button, so was wondering is there something i can call to make this happen? I dnt see any method attached to UINavbarController docs for this.
try popViewController:
[self.navigationController popViewControllerAnimated:YES];
Try looking at the UINavigationController docs instead, it's the fourth of 8 instance methods:
popViewControllerAnimated:
Pops the top view controller from the navigation stack and updates the
display.
- (UIViewController *)popViewControllerAnimated:(BOOL)animated

dismissModalViewController multiple

So, I am using a RootViewController from which you can display first ViewController Categories and then from Categories you display next ex. Music
RootViewController -> Categories -> Music
In RootViewController I use this
[self presentModalViewController:categoriesView animated:NO];
to present the modal view and then dismiss it from Categories with
[self dismissModalViewControllerAnimated:NO];
From Categories to Music I use again
[self presentModalViewController:fruitView animated:NO];
to present the Music modal view and then dismiss it in music with again the same as above.
Is there a possibility to dismiss two modal views? I want a method that leads from Music back to RootViewController, dismisses both last modal views.
Any ideas?
Hi Use this Following code[[[self presentingViewController] presentingViewController] dismissModalViewControllerAnimated:YES];
Are you sure you want to use modal views for this? It sounds like what you're trying to do is better solved with a UINavigationController, where you can push and pop view controller's in a stack (and there's a popToRootViewControllerAnimated: message you can use).
This is how drill-down navigation is idiomatically handled in iOS (in the iPod, Notes, Contacts, Videos, Photos apps for example).
There's sample code for this in Xcode, I believe.
UINavigationController has a popToRootViewControllerAnimated: method, which per the documentation:
Pops all the view controllers on the
stack except the root view controller
and updates the display.
Use popToRootViewControllerAnimated method of UINavigationController.
[self.navigationController popToRootViewControllerAnimated:YES];
What you're talking about here, going from more general to more specific views, is better handled with a UINavigationController pushing and popping views. These are the views which slide left and right on the screen. Pushing means it slides in from the right (and shows a new, more specific view). Popping slides back to the right and shows a more general view.
A modal view controller is the one that slides in from the bottom of the screen. Look at the iPod app on your device for the way to handle this.
I use a nice utility method to do this... see here:
How to dismiss the two or more dismissModalViewController?
Use This, In music view write this for dissmiss 2 view .
[RootViewController dismissModalViewControllerAnimated:YES];
Here RootViewController is an object of RootViewController
Hope this will help u.