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];
}];
Related
I have a ViewController with an UISearchController inside (with a table view on it). I've added this line on didSelectRowAtIndexPath::
[self dismissViewControllerAnimated:YES completion:nil];
For some reason, the viewController isn't being dismissed and instead, the keyboard is being dismissed (the searchController becomes inactive), to dismiss the viewController I have to reselect a cell on the table (and then didSelectRowAtIndexPath: is being called twice).
Any idea why is it happening?
Thank you!
This is probably happening because UISearchController inherits from UIViewController and therefore the controller being dismissed in didSelectRow is actually the search controller.
Perhaps simply try dismissing twice so that it removes the search controller followed by your custom view controller:
[self dismissViewControllerAnimated:YES completion:nil];
[self dismissViewControllerAnimated:YES completion:nil];
Try to resigning keyboard first and then dismiss vc.
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 ...
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];
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.
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