iOS back to root ViewController in the modal and navigation uiviewcontroller - ios

I have a structure about navigation and many page have modal (popup) on the uiviewcontroller(UINavigationController).
When I disconnect the bluetooth, I need back to the root the viewcontroller.
So I set the dismiss and popToRoot in the disconnect method
-(void) disconnect
{
....
[appDelegate.window.rootViewController dismissViewControllerAnimated:NO completion:nil];
NSLog(#"appDelegate.window.rootViewController:%#",appDelegate.window.rootViewController.class);
// show log appDelegate.window.rootViewController:UINavigationController
[appDelegate.window.rootViewController.navigationController popToRootViewControllerAnimated:YES];
....
}
But when I run the program and disconnect bluetooth,
In the case 1: modal the viewcontroller showing,
It will dismiss the modal viewcontroller, the dismiss was correct.
But there are not back to the root navigation controller after dismiss modal viewcontroller.
In the case2: just in the uinavigation controller page.
when I disconnect the bluetooth, there are not back to the root navigation controller.
How can I back to the navigation root page?where are my fails?
thank you very much.
// ------ answer -------
change code to
[appDelegate.window.rootViewController dismissViewControllerAnimated:NO completion:nil];
[self performSelector:#selector(gotoRoot) withObject:nil afterDelay:0.50];
- (void) gotoRoot {
UINavigationController *myNavCon = (UINavigationController*)appDelegate.window.rootViewController;
[myNavCon popToRootViewControllerAnimated:YES];
}

From the class you presented your modal view call dismiss of modal and then perform selector after some delay and then do the here is the sample code
- (void) dismissAndGoToRoot {
[self dismissViewControllerAnimated:YES completion:nil];
[self performSelector:#selector(gotoRoot) withObject:nil afterDelay:0.50];
}
- (void)gotoRoot {
[self.navigationController popToRootViewControllerAnimated:NO];
}

From apple developer documentation about dismissViewControllerAnimated:completion:
completion: The block to execute after the view controller is dismissed. This block has no return value and takes no parameters. You may specify nil for this parameter.
So I think this is better solution
[self dismissViewControllerAnimated:YES completion:^(){
[self.navigationController popToRootViewControllerAnimated:NO];
}];
Using completion block is better than afterDelay. How do you choose the good delay ? What happens if too short ? If too long, execution code waits for nothing ...

Related

dismissViewController clear the screen but doesn't dismiss

I have 2 screens:
The first call the second with the following code:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:kDetailSegue]) {
[NSThread detachNewThreadSelector:#selector(loadingThread) toTarget:self withObject:nil];
TagDetailControllerViewController* detailController = segue.destinationViewController;
detailController.location = self.recentLocation;
}
}
The kDetailSegue is a present modally - presentation default - transition: default
In second ViewController, I'm trying to dismiss the screen:
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
It is not clear what you want to dismiss in your second view controller, so I will try to present the most likely scenarios:
If you want to dismiss the view controller presented modally (TagDetailControllerViewController), you need to dismiss it modally too.
This can be achieved by calling in your TagDetailControllerViewController itself:
[self dismissViewControllerAnimated:YES completion:nil];
Which works because, according to Apple's documentation:
If you call this method on the presented view controller itself, it automatically forwards the message to the presenting view controller.
Also, if you want to dismiss it directly from the view controller you used to present it, you can do it as follows:
[self.presentedViewController dismissViewControllerAnimated:YES completion:nil];
Finally, if what you want is to dismiss a view that was pushed in your UINavigationController, then you can just pop it from the stack:
[self.navigationController popViewControllerAnimated:YES];
As you can see, the way a view is dismissed really depends on the way it was presented.
try this
[self.presentingViewController.presentingViewController dismissViewControllerAnimated:YES completion:NULL];

Dismiss 2 ViewControllers

I'm making an app whereas a popover ViewController modals to a new ViewController on a button press. When the user is done in the new VC, he/she presses ok and that should be dismissed alongside with the popover ViewController. I tried to use a notification to trigger the popover VC to close, but I can't as the other is being dismissed at the same time.
I see that the dismissing code has a completion token:
[self dismissViewControllerAnimated:YES completion:nil];
How can I set the completion:popoverVC and make that handle it?
Thanks a lot!
You can try:
[self dismissViewControllerAnimated:YES completion:^{
[self.parentViewController dismissViewControllerAnimated:YES completion:NULL];
}];

Dissmis a modal viewcontroller on a Storyboard

I'm developing an iPhone application with latest SDK.
I don't know how to dismiss a ViewController. I've added a back button and this is what I do:
- (IBAction)backButtonClicked:(id)sender
{
[self.navigationController dismissModalViewControllerAnimated:YES];
}
I have also tried:
[self.navigationController popViewControllerAnimated:YES];
But either works. I've added a breakpoint and it stops on it.
And I use a Modal segue to navigate to this ViewController.
How can I dismiss this View Controller programmatically?
Try [self dismissViewControllerAnimated:YES completion:nil];
- (IBAction)backButtonClicked:(id)sender
{
[self.presentingViewController dismissViewControllerAnimated:YES
completion:nil];
}
Is the VC being modally displayed an instance of your own view controller subclass, or did you wrap that inside a UINavigationController? If the former, try
[self dismissModalViewControllerAnimated:YES];
[self.presentingViewController dismiss...] will also work, but only for iOS 5+
create a custom segue,then button action choose the custom segue
http://jeffreysambells.com/2014/02/19/dismissing-a-modal-view-using-a-storyboard-segue

A method that dismisses a `modalViewController` and presents another

The thing is: I have a modalViewController presented with a button that triggers an IBAction like this:
-(IBAction)myMethod
{
[self dismissModalViewControllerAnimated:YES];
if([delegate respondsToSelector:#selector(presentOtherModalView)])
{
[delegate presentOtherModalView];
}
}
in the root view that is the delegate for that modalViewControllerI've implemented the presentOtherModalView delegate method and it looks like this:
-(void)presentOtherModalView
{
AnotherViewController *viewInstance = [[AnotherViewController alloc]initWithNibName:#"AnotherViewController" bundle:nil];
viewInstance.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:viewInstance animated:YES];
[viewInstance release];
}
The problem is this second modalViewController is not being presented. It gives me the message wait_fences: failed to receive reply: 10004003... How should this be done?
Because they are executed exactly after each other (they don't wait for the view to disappear/appear), it doesn't get executed. Because there can only be one ModalViewController on the screen at a time, you have to first wait for the other ModalViewController to disappear before the next one is put on screen.
You can do this creatively how you want, but the way I did it was something like:
[self dismissModalViewControllerAnimated:YES];
self.isModalViewControllerNeeded = YES;
And then in the underlying ViewController, in the viewDidAppear method, I do this:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if (self.isModalViewControllerNeeded) {
[self presentModalViewController:viewInstance animated:YES];
self.isModalViewControllerNeeded = NO;
}
}
Hope it helps!
It is because the dismissModalViewControllerAnimated takes some time to dismiss with animation and you are calling another view to present as modal view before dismissing the 1st modal view so the presenting modal view call was rejected. You should not perform animations when you are not on the view after completely dismissing only you can call another view. To solve this problem call the present modal view after 2 or 3 seconds using time interval or use completion block for dismissModalViewControllerAnimated
You can achieve it by using this
[delegate performSelector:#selector(presentOtherModalView) withObject:nil afterDelay:3];

Dismissing 2 ViewController consecutively

I try 2 ways to dismissed 2 viewcontrollers consecutively but only one of them got dismissed not the second one
method1
-(void) LoginDone:(NSNotification *)notif
{
[self dismissViewControllerAnimated:YES completion:NULL]; //previous viewcontroller
[self dismissViewControllerAnimated:YES completion:NULL]; //current viewcontroller
}
method2
-(void) LoginDone:(NSNotification *)notif
{
[self dismissViewControllerAnimated:YES completion:NULL];
[[NSNotificationCenter defaultCenter] postNotificationName:#"LoginDone2" object:nil];
}
-(void) LoginDone2:(NSNotification *)notif
{
[self dismissViewControllerAnimated:YES completion:NULL];
}
I need to find out a way to dismiss both the previous viewcontroller and current viewcontroller consecutively.
This is now an old question, but it seems to be exactly the problem I am having presently.
Here what I did:
[self.presentingViewController.presentingViewController
dismissViewControllerAnimated:YES completion:nil];
And it works for me. I hope it can be useful to someone.
By calling
[self dismissViewControllerAnimated:YES completion:NULL];
you are telling self to dismiss the view it presented. Telling twice the same self object to dismiss the view it presented, will not change the result. In other words self cannot represent the "current view" and the "previous view" at the same time as per your comment to the code. self is just a single controller representing a single view, either the current or the previous one.
To fix this, you should send the dismissViewControllerAnimated to self (that presented the top-most view, I assume) and to the other view controller object that presented the previous view.
In other words, I would expect something like this:
-(void) LoginDone:(NSNotification *)notif
{
[self dismissViewControllerAnimated:YES completion:NULL];
[self.previousController dismissViewControllerAnimated:YES completion:NULL];
}
Actually, you could send just one message to the second view controller and both views would be dismissed (source):
If you present several view controllers in succession, and thus build 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 know this is an old question but maybe somebody will look for solution on this issue so here it is:
-(void) closeModalViews
{
[previousVC dismissViewControllerAnimated:YES completion:^(void) {
[self dismissViewControllerAnimated:YES];
}];
}
I like JPetric's idea, but first you must dismiss the current view controller's view and only then can you dismiss the presenting view controller's view.
[self dismissViewControllerAnimated:NO completion:^(void) {
[self.presentingViewController dismissViewControllerAnimated:NO completion:nil];
}];
As far as I could understand you are trying something like below:
There are 2 view controllers.
You want both of them to be vanished.
Another controller comes in.
But the fact is only one controller is displayed, why you would need to dismiss 2 then?
You can use self.view.hidden=true; on the jumped viewcontrollers while animating back to the first viewcontroller. Using [self.presentingViewController dismiss...] is not working for me without hiding.

Resources