After presenting another view on my rootview, then I dismiss it, I want to refresh or reload my view, is it possible?
Send the view setNeedsDisplay message.
I define a simple protocol for modal view controllers to use to notify their parent that they're done:
#protocol ModalViewControllerDelegate <NSObject>
- (void)modalViewControllerDone:(UIViewController*)viewController;
#end
The parent then implements this protocol, and assigns itself to the modal view controller's delegate property. When the modal view controller is finished, it calls [delegate modalViewControllerDone:self]. The parent then dismisses the modal view controller and can do whatever else it wants (in your case, reload something).
Related
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.
What is the a way for the modal controller to talk to the presenting controller.
In my case i m presenting modalviewcontroller without using delegate. But want to dismiss modalviewcontroller using delegate protocol.
SO can i dismiss modalviewcontroller using delegate protocol where i m presenting modalviewcontroller without using delegate.
The modal controller can dismiss itself. Within the modal view controller, use [self dismissModalViewController animated:YES] (or NO if you don't want to animate it). If you include that line of code in the modal controller, then you should be okay!
dismissModalViewControllerAnimated:
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.
via iOS Documentation
You can also access the parent view controller through [self.parentViewController ...]
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 have a view in my app that displays a UITableView. This view is created in a nib file and has a custom view controller. The UIViewController subclass for this view acts as the Datasource and Delegate for the UITableView.
My UITableView displays several rows based on my data. Then, the last row displays different text: "Add another...". If the last row is selected, I present a modal view controller (to allow the user to add more data). When I dismiss the modal view controller, I again see the original view (as expected) and all appears to be well. However, when I try to interact with this view, the app crashes.
From placing several NSLog() statements through the UIViewController (for the UITableView), I have determined that the -dealloc method is being called just after the modal view is dismissed. This explains the crash when I try to do something with that view. However, I have no idea why -dealloc is being called on this view controller.
To dismiss the modal view controller, I have:
[self dismissModalViewController:YES];
As the code in an IBAction method in the modal view controller's UIViewController. This action is tied to a cancel button in the corresponding nib file.
In addition, my understanding from the View Controller Programming Guide is that it's OK to dismiss the modal controller from within itself, but it's more robust to use delegates. I was initially using a delegate, but took the delegate out to simplify debugging. I just put the delegate back in to double-check, and the same behavior occurs when using delegates. The modal controller's action method calls is implemented as:
[[self delegate] myModalViewController:self didAddObject:obj];
The delegate implementation in the parent view controller is:
[self dismissModalViewController:YES]
If anyone has seen this before or has any suggestions of what could be happening or how to debug this, I would greatly appreciate it.
If -dealloc is being called, something is releasing the view controller. Try implementing -release in your view controller:
-(void)release {
NSLog(#"view controller released");
[super release];
}
so that you can use the debugger to inspect the call stack when this unexpected release message happens.
Its dangerous to call dismissModalViewController from the modal view controller itself (message will be forwarded to parent view controller), if you have not retained it elsewhere. Normally, the parent view controller is responsible for dismissing the modal view controller it presented.
I have a view controller which presents a modal view when a certain button is tapped. Upon closing the modal view and re-revealing the original view underneath, I want a refresh method to be called. How do I call this refresh: method in OriginalViewController from ModalViewController?
I know this works if I do it in -viewDidAppear, but I only want it to happen when the modal view closes, not every single time.
As you can see in the View Controller Programming Guide, the recommended way is to use delegation.
How do you do it is up to you, but a standard way to so would be to define a protocol such as:
#protocol RecipeAddDelegate <NSObject>
- (void)modalViewControllerDismissed:(ModalViewController *)modalViewController;
#end
Then on your OriginalViewController you can implement that method, and act when the modal view controller has been dismissed:
- (void)modalViewControllerDismissed:(ModalViewController *)modalViewController {
[self refresh]; // or anything you want to do
}
As an additional comment, the guide I linked suggest that you should dismiss the modal not from the modal itself but from the controller that opened it. In the example, they create the delegate protocol a bit different, so it has methods for the original controller to be informed of the actions the modal controller does, and be able to decide when to close it.
Have a look at the View Controller Programming Guide, specifically, the section on dismissing a modal view.
The OriginalViewController should have a protocol method called by the ModalViewController when it's done. It should be the OriginalViewControllers responsibility to dismiss the modal view and perform any tasks it needs to on itself, such as refreshing itself.