dismissModalViewControllerAnimated not working - iphone

I have a UITabbarController with a UINavigationController. The view in the NavigationController presents an MVC (AddClockNavigationController). This MVC has a nib with an view and an UINavigationController. The NavigationController.view is added as an subview to the MVC's view.
The NavigationController in my MVC has two buttons, an Cancel and an Done. When pressing either one of them the MVC should be dismissed.
The IBActions of these buttons are in the UINavigationController's view (AddClockViewController), but whenever pressing them the MVC does not dissappear.
If I put the actions into the MVC, it does disapear.
If I put the function in my MVC and call it from my viewController using [self.parentViewController myFunction] it does not disappear.
How can I get it to disappear from my view?
I guess my explenation is quite messy but I hope you understand it.
A view from my IB:
Best regards,
Paul Peelen
Edit
I have tried this with [self dismissModalViewControllerAnimated:YES];, [self.parentViewController dismissModalViewControllerAnimated:YES];, [self.navigationController dismissModalViewControllerAnimated:YES];, [self.parentViewController.navigationController dismissModalViewControllerAnimated:YES]; and, as stated, with a function in the parentView dismissing it. Nothing works.

When some view controller presents another one, it becomes a parent view controller. So if you want to dismiss your modal view controller, then you have to choices:
from the parent view controller call
[self dismissModalViewControllerAnimated: YES];
OR
from the modal view controller call
[self.parentViewController dismissModalViewControllerAnimated: YES];
You actually don't need the navigation controller (cause you don't push/pop any view controllers). Just add the UINavigationBar to your MVC and place buttons on it. Then add actions to them and do choice #2.
Your code is not working because navigation controller has no parent, as it wasn't presented as modal.

One situation is that dismiss{Modal}ViewControllerAnimated is called before presented viewController's viewDidAppear is called. In such situation, the presented is presented with animated == YES. and before the presented is fully appeared, it got dismissed.
To fix it, you need to check at the point of time for dismissing, check if viewDidAppear is called, if not, defer the dismissing in - viewDidAppear.

Related

If "setNavigationBarHidden:YES", then how to come back to previous controller?

I don't want to let the navigation controller show its navigation bar in the whole project.
Now there are three view controllers
(1) Login view controller
(2) Sign up view controller
(3) Home view controller.
I just hope to use action(which can be triggered by any kind of event, i.e. drag gesture, not necessary the pressing button) to switch between these view controllers. But I found once I get to the "signup view controllers", I can not go back to the login view controller, since there is no "BACK" navigation bar.
Questions:
How "PUSH" in one view controller, then "POP" in the other view controller?
Or there is some different way to solve this problem?
Thank you so much, any suggestion is great.
To programmaticaly go backward in a navigation controller's navigation stack, call this method:
[self popViewControllerAnimated:YES];
When and where you call this is up to how you want your app to flow. Essentially, the default navigation controller calls this automatically when the navbar's back button is pressed. But if you hide the navbar and still need to pop back, you can call this method to pop back.
As for pushing forward, it's simply a matter of creating a Push segue on the storyboard, giving it a name, and then in your code, call this method:
[self performSegueWithIdentifier:#"segue_YOUR_SEGUE_ID" sender:self];
On the question of your app, what probably makes most sense is for the login view be a view by itself. It should contain a modal segue to a sign up view for new users as well as a modal segue to the home view controller (which may or may not need to be embedded in a navigation controller).
Performing a modal segue works exactly the same as a push segue (if you're using storyboards. Hook up the segue, choose a modal segue, then call the performSegueWithIdentifier: method in your code when you need the segue to occur.
Dismissing a modal view is slightly different, but still quite simple. It goes like this:
[self dismissViewControllerAnimated:YES completion:nil];
It's fairly check to do with an 'if' statement...
if (self.navigationController.navigationBarHidden == NO) {
//YOUR ACTION
}
Hope that helps!

popToRootViewControllerAnimated doesn't modify attached navigationItem

My UIViewController calls a function on my rootViewController which then called popToRootViewControllerAnimated to return the view to the rootController. This all works - great!
Unfortunately the UINavigationItem (toolbar at the top) seems to display a mashup of both the rootViewController and the UIViewController that has just been removed.
What do I need to do? What have I done wrong?
The navigation bar doesn't remember changes that were made to it, so when you push a new controller, the navigation bar is altered to give the title of the new view controller, but it doesn't store what was there for the previous view controller.
You will need to recreate the items in the toolbar each time you come back to the view controller that has custom items.
You might be able to do this on viewWillAppear instead of viewDidLoad. I can't recall exactly, but you should recreate custom controls on navigation toolbar because it does not get preserved when a new view controller is pushed.
It seems that calling popToRootViewController from the rootViewController messes things up. TO rectify this I called the following from within the calling UIViewController
[self.navigationController popViewControllerAnimated:YES];

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.

UINavigationController return to first view

I am using a UINavigationController to slide from a UITableViewController to another view. In that second view I have created a custom "Back" button which is attached to an action.
What code do I use to return to dismiss the current view and slide back to my first view? I need something that is the equivalent to [super dismissModalViewControllerAnimated:true]; but obviously this is not a modal view.
Thanks.
Look at one of the following three methods on your navigation controller:
popViewControllerAnimated:
popToRootViewControllerAnimated:
popToViewController:animated:
Depending on how you want to handle it of course. Generally one just uses the first method to go back to the last view (the one that pushed your current view onto the navigation stack).
Use popToRootViewControllerAnimated method in UINavigationController:
[self.navigationController popToRootViewControllerAnimated:animated];

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.