i'm developing an app for iphone, and i use
[self presentModalViewController:aViewControllerInitializateBefore animated:YES];
Can you tell me what happens to the current viewController when i use this?
The current view controller stays "underneath" the modal view controller and will reappear when you call
- (void)dismissModalViewControllerAnimated:(BOOL)animated
either on the modal view or the parent/presenting view controller (as the parent/presenting view controller's view is no longer visible, it's view may be unloaded when the system requires memory, and reloaded on dismiss).
From this method's documentation:
The parent view controller is responsible for dismissing the modal
view controller it presented using the
presentModalViewController:animated: method. If you call this method
on the modal view controller itself, however, the modal view
controller automatically forwards the message to its parent view
controller.
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.
Also note the change in iOS 5
Prior to iOS 5.0, if a view did not have a parent view controller and
was being presented modally, the view controller that was presenting
it would be returned. This is no longer the case. You can get the
presenting view controller using the presentingViewController
property.
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];
Lets say you present modal view controller (which is navigation controller) and push onto navigation stack 3-4 view controllers. Would dismissing modal view controller also pop these controllers from navigation stack, or will they continue to linger in memory?
I apple doc it states that when presenting multiple modal view controllers, if you dismiss the root one, all other will be dismissed, but animation of dismissal will happen only once. There is, however, no mention, what if you had pushed some controllers on modal view controller and then dismissed it.
When you dismiss the modal view controller, it will be deallocated from memory. So unless you keep a reference to it, everything will be removed, including its inner view controllers in the stack.
However, if you do keep a reference to it, it will stay alive when dismissed, therefore keeping its current state. Next time you present it, it will be just as you left it.
The navigation controller contains the view controllers that are pushed within it. So when the navigation controller is presented modally and then dismissed, it's (contained) view controller stack gets cleaned up, too.
If you want to dismiss a popover -- for example, from a button within the popover's contentViewController you must --
Create a reference to the popover to be held by view controller which creates it
Create a notification from the contentViewController to let the owning view controller know that it should be dismissed, or alternately create a delegate for the same purpose
Send the notification or delegate message when the popover is ready to be dismissed
Call dismissPopover:animated when the notification or delegate method is called
Meanwhile, from a UIViewController you can access the modal view controller, the parent view controller, the navigation controller, the split view controller, the tab bar controller, the search display controller, the child view controllers, the presenting view controllers, and the presented view controllers.
Is there a better approach to do this from popover's contentViewController?
Unfortunately, you'll have to create a weak property reference to said UIPopoverController as there's no way to access it from within the content view controller.
I was surprised how UIViewControllers can access the modal view controller, the parent view controller, the navigation controller, the split view controller, the tab bar controller, the search display controller, and as of iOS 5, the child view controllers as well as presenting and presented controllers...but not the popover controller (granted popovers aren't UIViewControllers but still).
Technically, there's a private, undocumented method to retrieve the popoverController that the UIViewController is in...I have no idea why they never made it public given that it should be exactly the same as any of the above controllers.
Though even in the private, undocumented world, there's no equivalent to dismissModalViewcontrollerAnimated:. You'll still have to get that reference then dismiss it that way.
Another way to solve this is to create an abstract view controller (for all your view controllers) that adds an NSNotification observer to a method such as -(void)closePopoverIfNecessary:(NSNotification*)notification and have child classes optionally implement the method to close their popover(s) if open. Then from within the popover's controller you fire the notification to close it. You could also pass other info via the notification (userInfo) if needed.
This way there's no need for the parent references.
After a modal view controller is dismissed, is there any delegate method called to bring the parent view controller to the front?
I ended up using delegation from Apple's View Controller Programming Guide for iOS :
http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/ModalViewControllers/ModalViewControllers.html#//apple_ref/doc/uid/TP40007457-CH111-SW14
When it comes time to dismiss a modal view controller, the preferred approach is to let the parent view controller do the dismissing. In other words, the same view controller that presented the modal view controller should also take responsibility for dismissing it whenever possible. Although there are several techniques for notifying a parent view controller that it should dismiss its modally presented child, the preferred technique is delegation.
There was a good example in the CoreDataRecepies sample code when adding a recipe that fit what I was trying to do.
i.e., at the "same time" view[Will|Did]Disappear: is being called on the modal view controller as its view is being dismissed, the view[Will|Did]Appear: are sent to the view controller that is being revealed
the code in here should not really need to differ from the reveal code you used when it was first displayed,
if you need data passed back from the modal controller to the one that displayed it, generally the code that dismisses the modal controller lets the other one know
parentController.item = self.chosenItem;
[parentController dismissModal…
I have a main screen that presents a modal view controller.
When the modal controller is done it calls a method on the parent to dismiss the modal and then display a different modal view.
The problem is that after dismissing the modal view controller (the view does correctly disappear) the subsequent presentModelViewController doesn't do anything.
If I look at the modalViewController property on the root controller I can see that after doing the dismiss it is still set to the old modal controller. As noted above the view is no longer visible and also if I profile the application there are no instances of that view in memory.
Any ideas?
The problem was that the modal controllers viewDidDisappear had not been called before I was adding a new modal controller.
Once I ensured that I only tried to add a new modal after the original modal viewDidDisappear had been called it worked ok.