I'm making a UIPopoverController and displaying it. All is well, content is loading... except I need to dismiss the popover when a button is pressed. The UIPopoverController's delegate is set to self but I don't know how to call a method in the parent view controller.
UIPopoverController has method
- (void)dismissPopoverAnimated:(BOOL)animated
so you can dismiss it directly from itself.
Unless you meant that you want to dismiss popover from its contentViewController, then there is at least dozen of answers regarding that here - for instance similar to this one
Related
UIPopoverController has a .isVisible property to tell if the popover is on the screen or not.
Is there an equivalent for the new UIPopoverPresentationController?
It's a UIPresentationController, so it has a presentedView, so you can ask whether that presentedView has a non-nil window.
But the real answer is that you are looking completely in the wrong place. UIPopoverPresentationController is nothing like the old UIPopoverController; they have almost nothing in common and they are not managed in similar ways. A popover is now just a presented view controller. Concentrate on the view controller. You just dismiss it, like any presented view controller (self.dismissViewController...). This is the whole point. You no longer retain a reference to anything; you no longer have to manage anything; it's just like presenting and dismissing any modal dialog / view.
in my iPad-app I connected a UIButton to another UIViewcontroller by just dragging in Storyboard and chose popover as segue. Everything is working fine, but the user can dismiss the popover by touching just somewhere besides the popover right.
How can I detect that the popover has dismissed in iOS8? In iOS7 I could just use the UIPopoverDelegate -popoverDidDidmiss...
But this is not working anymore!? I googled a lot but could not find any solution.
You put your
-(void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
in the UIViewController where the start UIButton is ? (not in another popover UIViewcontroller ?)
That work well for me with iOS 8.1...
You have to delegate to the initial UIViewController for that.
I assume you set the delegate properly, but do you retain the popover, i.e. assign it to a strong property? In ios7 if you didn't retain the popover you would get exception: '[UIPopoverController dealloc] reached while popover is still visible.' In ios8 this is not longer the case, so you get the working popover and you can dismiss it, but the delegate methods are not called anymore.
(Frankly speaking, I'm not sure why this is so. I'd suppose that at least "should dismiss popover" should be called anyway).
You should probably use UIPopoverControllerDelegate and the method
popoverControllerDidDismissPopover:
to accomplish what you need.
in iOS8, it is using the UIViewController's UIPopoverPresentationController to present the popover. (Optionally you still can use back the old UIPopoverController to build the popover manually.
If you are using storyboard on iOS8, you can set the UIViewController's popoverPresentationController delegate to handle the followings:
popoverPresentationControllerShouldDismissPopover:
popoverPresentationControllerDidDismissPopover:
I'm having trouble piecing this all together. I have a view controller that opens up another (pushes it on to the navigation stack). On that presented view controller, the user enters a value in a text view. When the user pushes the back button in the navigation, I want to be able to pass the value that they entered in the text view back to the presenting controller.
I've looked for a way to use unwind segue with the back button but haven't found anything. When I create my back button (programmatically) I use initWithTitle:style:target:action but I'm not sure how in implementing the action method that I'll be able to access the value set in the presented controller. Might have to use a delegate to link the two, but not sure of the exact integration point for this scenario.
I feel like I'm so close here and a little help would get me there. Thanks!
The two most common models to use for this interaction are for the child view controller to have either a delegate or a completion block. Either would be set in the prepareForSegue method. My personal preference is the completion block method just because it keeps code contained, but ymmv.
There are also multiple models for detecting when your child view controller is dismissed and you need to invoke the delegate and/or completion:
Use a custom back button. Not a fan of this as it can be an issue to create a back button that really looks and acts like the Apple original, especially if supporting iOS 6 and iOS 7.
Hook viewDidDisappear and see if you're still in the navigation controller's viewControllers array. This is better as the back button works right, but it still feels kind of hokey.
Use the UINavigationBarDelegate method navigationBar:shouldPopItem: This is attractive, especially if you have other validation that needs to happen like checking for saved/unsaved values. To implement this you'll have to subclass UINavigationController and forward the method to your child view controller.
EDIT: Details on Option 2:
-(void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
if(![self.navigationController.viewControllers containsObject:self])
{
// We're not still in the navigation stack so we must've been
// popped. If we were pushed, viewDidDisappear would be called
// but viewControllers containsObject:self would be true
}
}
EDIT: Clarified Option 3: in your navigation controller subclass
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item
{
UIViewController* top = self.topViewController;
if([top respondsToSelector:#selector(navigationBar:shouldPopItem:)])
return [(id)top navigationBar:navigationBar shouldPopItem:item];
return [super navigationBar:navigationBar shouldPopItem:item];
}
Then you can implement navigationBar:shouldPopItem: in the classes that need the functionality.
the back button does not actually comes up with any event associated with itself so that you can pass the values between the previous and to be Popped ViewController.
You would have to implement Delegate pattern to pass values. In this case as you cant catch when backButton is pressed, you need to use custom leftBarButtonItem or use a image with < in itself.
When a popover is open it closes if you click of it. Is is possible to stop this? Basically i have the following problem.
When a popover closes i need a function to be processed. If i set a button with a dismiss function from the popover then i can put the function in the dismiss method however this isn't detected if the user clicks of the screen.
So is is possible to stop a popover closing if you click off it.
or
Is it possible to detect this allowing the function i require to be called.
Thanks
James
Can use these two methods, but the second one suits your scenario:
/* Called on the delegate when the popover controller will dismiss the popover.
Return NO to prevent the dismissal of the view.
*/
- (BOOL)popoverControllerShouldDismissPopover:(UIPopoverController *)popoverController;
/* Called on the delegate when the user has taken action to dismiss the popover.
This is not called when -dismissPopoverAnimated: is called directly.
*/
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController;
Remember to implement the UIPopoverdelegate and set the Delegate to self.
Assuming you are talking about the default behavior of popovers being dismissed when you tap outside of the popover, the solution to prevent this is to make the popover modal.
To do this, set the modalInPopover property to YES on the popover's content view controller.
BTW - if you want to detect when a popover is dismissed by the user by tapping outside of it, you need to implement the UIPopoverControllerDelegate method popoverControllerDidDismissPopover:.
I'm working on a problem where I have a ViewController which opens a popOver when a button is pressed and then in the popOver you can edit some settings which affect the content shown in the mother ViewController (for instance change the color of the View, change a map or a table there). This can be off course called whenever the popOver is dismissed, but it needs to be live up-to-date.
I tried using delegates, where I can pass over data or call a function but the function won't be started on a ViewController wchich isn't active, right?
I also tried NSNotifications but it didn't work either.
I found several questions like this on stackoverflow, but there is no real answer yet:
UIPopoverController button selecting method of another ViewController but not updating its view iOS
Refresh the view controller from popover
Refreshing a view from a popover
Refresh a WebView in a ViewController from another ViewController
how to refresh or reload a uiviewcontroller
Can somebody please explain a generall way with some code snippets how to get this fixed?
Delegation is a fine solution. The target view controller is presumably still visible underneath the popover (which shouldn't fill the screen). In this case when the target receives the delegate callback it can do any updates and refresh its views to update the UI without any limitation. In this situation both view controllers (the 'target' and the popover) would both be classed as 'active' as they are both visible on screen.