IOS Container View VC dismiss parent? - ios

I have 3 view controllers. Controller A calls B. B has a container view which contains C - a table view controller. How do I use the didSelectRowAtIndexPath method in C to dismiss both B and C and return to A?
I've tried this:
[self.navigationController.parentViewController dismissViewControllerAnimated:YES completion:nil];
this:
[self.navigationController.parentViewController dismissViewControllerAnimated:YES completion:nil];
And this:
[self dismissViewControllerAnimated:YES completion:nil];
None of which work.

Related

How to dimiss the top most viewcontroller only in iOS?

I have a situation like this:
Controller A present ControllerB present ControllerC.
Now I want to dismiss Controller C
But When I call [ControllerC dismissViewControllerAnimated]. Both ControllerB and ControllerC are dismissed .
How to dismiss ControllerC only
[ControllerB dismissViewControllerAnimated:YES completion:nil];
Or in cases where you don't have reference to the presenting view controller:
[ControllerC.presentingViewController dismissViewControllerAnimated:YES completion:nil];

Cannot close two UiViewControllers

I have a UiViewController A which opens a second UIViewController B as follows:
BViewController *BController = [Utilities getMainStoryBoardWithIdentifier:#"BViewController"];
[self presentViewController:webViewController animated:YES completion:nil];
Now on UiViewController B, when I want to close it, I would like to close the A also. So I'm using the following:
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
[self dismissViewControllerAnimated:YES completion:nil];
But only the B is closing...
Any idea ?
Can you please try following code :
[self dismissViewControllerAnimated:YES completion:nil];
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
Where self is your B controller. I've just tried the code and it works well. Tell me if any other help is needed.
Try using an unwind segue.
If you have X which presents A, which in turn presents B, add
func unwindToX(_ segue: UIStoryboardSegue) { }
to view controller X
Then in your storyboard, drag from the close button in B to it's exit and select unwindToX. Clicking the button will then dismiss both view controllers. This also works with view controllers pushed on to a nav stack, or a combination of both.

Dismissing previously presented modal view controller before currently visible one

I have 2 UIViewController's presented with [self presentViewController:viewController animated:YES completion:nil];, I want to dismiss the first one of them, without animation (It's not visible to the user anyway) and when the second one (currently visible) will be dismissed, the user will see the parent view controller who present them both.
- Parent
- First -> Dismiss first without animation
- Second -> Dismiss second with animation
How can I do that?
With your current view controller hierarchy if first view controller will be dismissed it will dismiss second view controller automatically. If you don't want that behaviour than make parent present second view controller. You can do that from first view controller by using [self.presentingViewController presentViewController:secondViewController animated:YES completion:nil]
Why do you want to do this?
You should do it like this for cleaner view hierarchy and better user experience:
Present first view controller :
[self presentViewController:viewController1 animated:YES completion:nil];
Dismiss first & present second view controller :
__weak MyViewController *aBlockSelf = self;
[self dismissViewControllerAnimated:YES completion:^{
[aBlockSelf presentViewController:viewController2 animated:YES completion:nil];
}];

chaining uiviewcontroller delegates

i have a uivewcontroller (let's call it A) that loads uiviewcontroller (B) setting it up as a delegate which i use to close B and continue code on A. There is also a scenerio where B leads to another uiviewcontroller C (again with a delegate). When C is closed i use it's delegate to return to B but in this scenario i also want B to be immediately dismissed and the code to return to A. Now, B->A works, and C->B works but doing C->B->A fails at B with an error:
"attempt to dismiss modal view controller whose view does not currently appear" it appears to be trying to dismiss view C again.
Both viewcontrollers are being dismissed with this code (though the code sits in different uiviewcontrollers)
[self dismissViewControllerAnimated:YES completion:nil];
Am I using delegates correctly for what i want, or should i be using a different process?
Code for option 1 (A->B, B<-A):
A -> B
scorer_turn *st = (scorer_turn *) segue.destinationViewController;
st.st_delegate=self;
st.league = _match.league;
st.match = _match;
st.leg = _leg;
st.set = _set;
B -> A
-(void)closeView{
[_st_delegate scorer_turn:self didFinish:YES];
}
-(void)scorer_turn:(scorer_turn *)controller didFinish:(BOOL)finish{
[self dismissViewControllerAnimated:YES completion:nil];
}
Code for option 2 (A->B, B->C, C->B->A):
as above plus:
B -> C
matchSummaryViewController *ms = (matchSummaryViewController *) segue.destinationViewController;
ms.match = _match;
ms.oneScreen = NO;
ms.delegate = self;
[[segue destinationViewController] setManagedObjectContext:self.managedObjectContext];
C -> B, B -> A
in C:
[_delegate matchSummaryViewController:self didFinish:YES];
in B:
[self dismissViewControllerAnimated:YES completion:nil];
[_st_delegate scorer_turn:self didFinish:YES];
in A (this is where the error occurs):
-(void)scorer_turn:(scorer_turn *)controller didFinish:(BOOL)finish{
[self dismissViewControllerAnimated:YES completion:nil];
}
If ViewController B is a modalViewController, and ViewController C is pushed onto the same modalViewController, then calling
[self dismissViewControllerAnimated:YES completion:nil];
should dismiss the entire modal view - as in, it'll dismiss C and skip B all-together (B wont even appear), which would cause problems if B tries to also call dismissViewControllerAnimated:completion: since there is no more modal view to dismiss.
Now, if you have some other set-up, such as B being a modal which, when pushing C, it actually dismisses itself and launches a new modal view (this would happen if you always use the presentViewController:animated:completion function), then you have other design problems - you shouldn't be swapping modal views like that, instead use
[self.navigationController pushViewController:C animated:YES]
to show the view and
[self.navigationController popViewControllerAnimated:YES]
to dismiss View C and return to View B.
This is assuming of course that you're using a navigationController to manage your views (which you typically should be doing).
If on the other hand you aren't using modal views at all, then dismissViewControllerAnimated:completion: isn't what you want to use at all.

dismiss viewController by using presentingViewController

I have three ViewControllers and its order is (A present B which presents C),
when I stay in the C viewController ,I have to dismiss ViewController to B viewController.
for C viewController ,its presentingViewCOntroller is B viewController
of course ,I can use
[self dismissViewControllerAnimated:YES completion:NULL];//self means C ViewController
But I was wondering I can also use the following method:
[self.presentingViewController dismissViewControllerAnimated:YES completion:NULL];
because the presentingViewController of C is B ViewController, but it did the same effect.
self means C ViewController while self.presentingViewController means B ViewController,but they also did the same work
The second question is I cannot use the following to dismiss two viewController in succession:
[self dismissViewControllerAnimated:YES completion:^{
[self.presentingViewController.presentingViewController dismissViewControllerAnimated:YES completion:NULL];
}]; //self means C viewController
Thanks for your help!
of course ,I can use
[self dismissViewControllerAnimated:YES completion:NULL];//self means C ViewController
This only dismisses C, not B as you seem to want.
But I was wondering I can also use the following method:
[self.presentingViewController.presentingViewController dismissViewControllerAnimated:YES completion:NULL];
Yes, this works. When in doubt, try it out.
The second question is I cannot use the following to dismiss two viewController in succession:
[self dismissViewControllerAnimated:YES completion:^{
[self.presentingViewController.presentingViewController dismissViewControllerAnimated:YES completion:NULL];
}]; //self means C viewController
That's not a question. Anyway, the reason it doesn't work is that after you dismiss yourself, your presentingViewController is nil. You need to store it in a temporary variable.
UIViewController *gp = self.presentingViewController.presentingViewController;
[self dismissViewControllerAnimated:YES completion:^{
[gp dismissViewControllerAnimated:YES completion:nil];
[self.presentingViewController.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}];
Of course, the two will have different animations, you'll need to decide which you prefer.
see documentation:
The presenting view controller is responsible for dismissing the view
controller it presented. If you call this method on the presented view
controller itself, it automatically forwards the message to the
presenting view controller.
Please check: self.presentingViewController.presentingViewController is A viewController or not.
if not, I think you need use delegate or handler.
In my case, I used a tabbarcontroller as a rootViewController. When I used self.presentingViewController.presentingViewController, I got rootViewController (tabbarcontroller) which it have no response to presentingViewControler method.

Resources