I have three view controllers, say A, B and C. I am navigating through this views like follows;
A -presenting-> B -presenting-> C -presenting-> B
And from B, if I dismiss I want to navigate to C. But instead of that, now it is moving to A. I can't use dismiss for navigation from C to B (some internal issues). So how can I fix this? Please help.
You hit into a limitation of dismissModalViewController: it will remove all of your modal views (source):
If you present several view controllers in succession, and thus build a stack of presented view controllers, calling this method on a view controller lower in the stack dismisses its immediate child view controller and all view controllers above that child on the stack. When this happens, only the top-most view is dismissed in an animated fashion; any intermediate view controllers are simply removed from the stack. The top-most view is dismissed using its modal transition style, which may differ from the styles used by other view controllers lower in the stack.
What you could do is using a UINavigationController and simply push/pop controllers on to it according to your requirements.
Alternatively, you could simply display the views managed by the various controllers you have by directly calling addSubview on your top view and making sure they cover the whole screen and that the managing controller is correctly retained/released (the view is automatically when you add/remove it to another view).
As a hint, you could do it like this:
where you have presentModal..., use addSubview;
where you have dismiss..., use removeFromSuperview;
store a reference to any view controller whose view you manage like I suggest here in retain/strong property.
Hi use the below code in "C" viewcontroller
[[[self presentingViewController] presentingViewController] dismissModalViewControllerAnimated:YES];
Related
Using storyboard , I'm invoking a segue (set type to modal) in order to display the second controller , and the same way to display the third controller. A->B->C. I expect dismiss B and C together , and return to A. There was no navigation view controllers , no popToRootViewControllerAnimated: .
In docs:
If you present several view controllers in succession, thus building a stack of presented view controllers, calling this method on a view controller lower in the stack dismisses its immediate child view controller and all view controllers above that child on the stack. When this happens, only the top-most view is dismissed in an animated fashion; any intermediate view controllers are simply removed from the stack. The top-most view is dismissed using its modal transition style, which may differ from the styles used by other view controllers lower in the stack.
I tried a variety of ways but failed. Am I missing something really simple ?
Try This
[self.presentingViewController.presentingViewController dismissModalViewControllerAnimated:YES]
Also try This
[self.parentViewController.parentViewController dismissModalViewControllerAnimated:YES];
In my application, I have to present two modal view controllers one above the other.
Lets say Modal View Controller B is placed over Modal View Controller A. Sometimes, there will be only A and no B.
I want to check from A that whether the top Modal View Controller is B. I know there is a method NSStringFromClass() but I can apply that only if I get the top Modal View Controller.
use (BOOL)[[youObjectInstance isKindOfClass:[ControllerClassYouWantToCheckAgainst class]]
Documentation here:
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Protocols/NSObject_Protocol/Reference/NSObject.html#//apple_ref/occ/intfm/NSObject/isKindOfClass:
iOS 5 introduces the concept of custom container view controller and provides API like addChildViewController. Question: can you add a view controller as a child and still present it using presentViewController? Does doing the latter automatically make it a child view controller of the presentingViewController?
That's not how it's supposed to be used.
The parent/child relationship is for when a view controller has subviews that are managed by their own view controllers, for example a UITabBarController, where the parent view controller draws the tabs and the child view controllers draw the content of each tab.
If you present a view controller using presentViewController, it generally takes over the whole screen, or appears in a modal so that the presenting view controller is no longer in control. In that scenario there's no reason for the presenter to be the parent because it doesn't need to cooperate with the presented controller - it just gets out of the way until the presented controller is dismissed again.
Why is it that you wanted to do this? If it's just so that the view controllers have a reference to one another and can pass data, there are other ways to do this (e.g. the delegate pattern, NSNotifications, or even just a property linking the two).
Here's the scenario, switchViewController is the view added to the main window. So switchViewController is the main view, so if I want to go view B, I will addsubview of view B, there isn't a need to remove switchViewController's view right?
The issue is after I go back from view B to switchViewController's view, the method viewWillAppear is not being called anymore.
Why is it so?
viewWillAppear: is not called automatically when a view is removed from or added to the view hierarchy. It is the responsibility of the view controller to call it at the right time. The built-in view controller classes do this whenever you present or push a new view controller. Since you do not use this mechanism in your app, the method doesn't get called (unless you call it yourself).
That's because it never disappeared, you were just putting something else in front of it. If you want to navigate from one screen to another and back, they should be separate view controllers, and you should be using UINavigationController and its pushViewController:isAnimated: method.
It's not getting called beause your just modifying the first view, not navigating to a different one.
You might consider embedding your view in a Navigation controller, then calling your ViewB with
[navigationController pushViewController:viewB animated:YES];
My application presents a modal view (A) from the main view that lets the user make a selection. When they make that selection it opens a second modal view (B) on top of the first one (A).
When I'm done with the second modal view (B), and want to dismiss it, I would like to dismiss the first one (A) and the second one (B) at the same time as I no longer need the user to return to that one (A) either.
The only thing I came up with is:
[self.parentViewController.parentViewController.parentViewController. dismissModalViewControllerAnimated:YES];
It works, but it just doesn't look correct. Is this OK to do or is there a more accepted way to do this?
I don't think that your way is wrong. It is what Apple documentation recommends:
If you present several modal view controllers in succession, and thus build a stack of modal view controllers, calling this method on a view controller lower in the stack dismisses its immediate child view controller and all view controllers above that child on the stack. When this happens, only the top-most view is dismissed in an animated fashion; any intermediate view controllers are simply removed from the stack. The top-most view is dismissed using its modal transition style, which may differ from the styles used by other view controllers lower in the stack.
(UIApplication.sharedApplication().delegate! as! AppDelegate).navigationController?.viewControllers.first?.dismissViewControllerAnimated(true, completion: nil)