Dismissing modalviewcontroller issue - iphone

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 ...]

Related

Dismissing modal view controller

Issue: When dismissing a modal view controller, the header on the presenting view controller is moved up (what looks to be around 20 pixels).
Steps to recreate:
Create a tab bar controller (T), inside create a navigation controller with (N) a root view controller (A).
Setup another view controller (B) (this is the view controller to be presented modally) with a delegate so we can notify the presenting view controller (A) when it should dismiss the modal (B).
Inside the navigation controller's root view controller(A) create an instance of (B) by instantiating it from the storyboard with it's storyboard id, then present (B) with [self.tabBarController presentViewController:(B) animated:YES complition:nil];.
Have a button on (B) that when pressed triggers the delegate function to notify (A) to dismiss (B) by using [self.tabBarController dismissViewControllerAnimated:YES complition:nil];
So far all works as expected. However once the modal view controller (B) is dismissed. The navigation header on (A) is moved up about 20 pixels.
I cannot figure out why the navigation header is moving up when the modal is dismissed.
In the presenting viewController add following code to the
-(void)viewDidAppear:(BOOL)animated method:
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];

What happen on current viewController when i call presentModalViewController

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.

Canceling a modal view & app crashes

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

UIViewController -dealloc Being Called After Dismissing 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.

Problem dismissing multiple modal view controllers

I am having trouble getting my modal view controllers to display properly. I have a parent view controller that is the delegate for modal view A. In modal view A I am presenting modal view B, and having the delegate dimiss modal view A.
When modal view B appears it seems to display but the screen dims, and the UI locks up, but the app doesn't crash. I set animation settings to NO and I am still getting the same issue.
Order of events:
Parent View show Modal View A
Modal View A shows Modal View B in Modal View A controller
Parent View dismisses Modal View A in Modal View A controller via delegation
This is where my UI hangs, I can see Modal View B but can't click on it, or do anything
You could use this
[[[self presentingViewController] presentingViewController] dismissModalViewControllerAnimated:YES];
A modal view controller must have a parent view controller in order to display. If you dismiss the parent view controller ("modal view A", in your case), behavior will be unpredictable.
If you're certain that nested modal view controllers are what you really want, you'll need to dismiss them in reverse order; wait until you're done with "B", then dismiss "B", then dismiss "A".
If you don't need the modal presentation style, you would be better off using a UINavigationController to maintain your stack of view controllers.
Update: here is how I would rearrange your order of events. Presented as code for clarity.
[parentView
presentViewController:modalViewControllerA
animated:YES]
[modalViewControllerA
presentViewController:modalViewControllerB
animated:YES]
[modalViewControllerA
dismissModalViewControllerAnimated:YES]
[parentView
dismissModalViewControllerAnimated:YES]
Solved by having my parentViewController act as the delegate. Here is my order:
[parentView presentViewController:modalViewControllerA animated:YES]
[parentView dismissModalViewControllerAnimated:YES]
[parentView presentViewController:modalViewControllerB animated:YES]
//Modal B dismisses himself
In my delegate method, I needed to make sure that I dismissed Modal A before presenting Modal B
For iOS 6+ and - presentViewController:animated:completion:
[[[self presentingViewController] presentingViewController] dismissViewControllerAnimated:YES completion:nil];
in Swift 2.1
you can try
self.presentingViewController?.presentingViewController?.dismissViewControllerAnimated(true, completion: nil)
works for me
View A -> View B -> View C
Apply this code in view C , you will be landing to View A
I have a main view and need to show a modalview1 where a button present a modalview2. Looks the same you needed.
But there is a button in the modalview2 which forwards to the main view.
So the solution is:
Main view presents UINavigationController with modalview1 as rootController. Then modalview1 present modalview2 by "[self.navigationController modalview2 animated:YES];".
When modal2 needs to forward to the main view, just make "[self.parentViewController dismissModalViewControllerAnimated:YES];" and UINavigationController is hidden.
Hope it's clear.
Simple:
Dismiss all views:
[self dismissModalViewController animated:YES];
[self dismissModalViewController animated:YES];
[self dismissModalViewController animated:YES];
[self dismissModalViewController animated:YES];
(one for each added modal view)
then present a new modal view controller
may be after long but.. I am in same problem and this is the only post with some answer.
I am not getting what you mean by setting delegate of a parentViewController to self is not allowed .
what I am doing right now is
[self presentModalViewController:ViewControllerA animated:YES];
[self dismissModalViewControllerAnimated:YES];// inside ViewControllerA
[self presentModalViewController:ViewControllerB animated:YES];
[self dismissModalViewControllerAnimated:YES];// inside ViewControllerB
Problem is after viewControllerA , viewControllerB view is not presenting.
Thanks,
Apple document about dismiss(animated:completion:) method.
In section Discussion, it said:
any intermediate view controllers are simply removed from the stack.
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.
In other words, if the view controller stack like following
Root -> A -> B -> C -> D ... -> Z
D calls dismiss method, all view controllers behide D, ex: (E ... Z), will be removed from the stack.