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.
Related
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.
I have a modal that I am calling presentModalViewController to display from a custom menubar. This menubar is overlaying a viewcontroller that is pushed from a tableView cell.
Now... that all being said, I need to find some way to jump the user back to the root of the tableView from the modal screen. Is this possible? I've been fighting with this for the past couple of hours with no results.
If you're starting from a tablview, drilling down to a detail view via a navigation controller, and then presenting a modal view controller on top of that detail view, you'd have two steps to get back to your list/tableview: First you'd dismiss your modal view controller, then you'd pop your detail view off your navigation stack.
That should put you back where you started (at the tablview), if I'm reading this correctly.
You could pass a reference to the navigation controller to the modal view, and then immediately after calling dismissModalViewControllerAnimated, you can use the reference to the navigationController to pop back to the root view controller.
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 confusion on canceling the modal views:
Case 1: I have a navigation view controller and I am presenting a modal view controller from this navigation view controller. Now, when I am to cancel this modal view from where should I call the dismissModalView method -- navigation view controller or the modal view controller?
Case 2: I have a modal view controller and I am presenting another modal view controller from first modal view controller. Now, when I am to cancel second modal view from where should I call the dismissModalView method -- frist modal view controller or the second modal view controller?
Will canceling it from a wrong place cause a app crash also?
An advisable way to handle modal view controllers is to us notifications to inform the class that presented it to release it. Generally, you use code similar to this to show a modal view.
SomeClass *yourViewController = [[SomeClass alloc] initWithNibName:#"SomeClass" bundle:nil];
[self presentModalViewController: yourViewController animated: YES];
[yourViewController release];
With the above code, your modal view should end up with a retain count of 1. When you dismiss it, the parent view will release it and it will be purged from memory. Your "close" button in your modal view should execute code that looks like this:
- (void)dismissSelf{
[[NSNotificationCenter defaultCenter] postNotifivationName:#"I'm done" object:self];
}
Back in your parent viewcontroller, ou should listen for this notification and then dismiss the modal view when the notification is posted.
That said, to answer your questions:
A modal view controller never dismisses itself. Post a notification and then let the navigation controller handle it.
You can't dismiss the first modal view until the second one has been dismissed. If you do, you will get a EXC_BAD_ACCESS error. Think of the second modal view as "inside" the first one. If the first is dismissed, the second one will be dragged away with it, but it hasn't been dismissed.
you should dismiss the modal view
controller.
you should dismiss it from the
second modal view controller.
the app crashes because when you trying to dismiss the modal view controller , the scope of corresponding view controller is lost, may be u released the view controller before dismissing
You always dismiss the modal view from the controller, where you presented it (with dismissModalViewControllerAnimated). So:
in the navigation controller
in the first modal view controller
I'm working on a dual-iPad/iPhone application.
I'm having a problem that is occurring on the iPad only:
Root view controller is a UISplitViewController on iPad, UITabBarController on iPhone
A modal UIViewController can appear over the root controller
A modal UIViewController can appear over the previous modal controller
On iPad, modal controllers are using UIModalPresentationStyle.PageSheet
Everything works, except dismissing the topmost modal controller from the iPad--the method is called, but the modal view controller doesn't dismiss. I dismiss by calling DismissModalViewControllerAnimated from the previous modal controller.
Any ideas why this wouldn't be working on the iPad?
In all cases, I call PresentModalViewController and DismissModalViewControllerAnimated from the parent controller to work its child modal controller.
I'm using MonoTouch (you can tell by my casing of methods), but that is probably irrelevant. I can take answers in Obj-C as well.
UPDATE, following might make what it should do more clear:
Root => Modal A => Modal B
Dismissing Modal B should just return
to Modal A
Dismissing Modal A should just return
to Root
Are you sure you are dismissing the right view? Inside the modal view, lets say that you want to dismiss the view with a button click. In that button's method, you want to call the DismissModalViewControllerAnimated method. Just say
[self dismissModalViewControllerAnimated:YES];
Present the modal window from the root
when finished, dismiss the view from the modal view's controller.
It's hard to really diagnose the problem without seeing how you are trying to present and dismiss the controller, but that should work. You shouldn't need to do anything from the parent controller once the new view is displayed...
Found a workaround. All of these conditions had to be met to fix it:
First modal has default ModalPresentationStyle
Second modal has UIModalPresentationStyle.PageSheet
My second modal is displayed in the ViewDidAppear of the first. For some reason, I needed to call PresentModalViewController from BeginInvokeOnMainThread. (A one-liner in MonoTouch) This is a trick I learned from Windows development and message pumps. I have seen iPhone devs do similar workarounds with timers--this is much better.
I will post-back if we have trouble getting this through the app store. But for now, it is a good solution for us.