How to detect when a popover deviates in iOS 9

I am updating the application to use universal storyboards. I created a popover segue for the new view manager using the interface builder, dragging it with a button on my new view manager and selecting "Present As Popover" as the segue view.

When the user clicks outside the popover (rejecting it), I need to get a notification in the view controller so that I can undo their actions. How can i do this?

Typically, I would create a popover manually and make myviewcontroller delegate to popover; letting me use the popoverControllerDidDismissPopover callback. However, this is deprecated in iOS9, and even if it weren’t, I had no idea where to find the popover so that I could install its delegate on my view controller.

+10
ios ios9 uistoryboardsegue uipopover universal-storyboard
source share
3 answers

Not sure which method you think is obsolete, but you can still use the UIPopoverPresentationControllerDelegate to achieve this. Something like:

 override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { if segue.identifier == "popoverSegue" { let vc = segue.destinationViewController sortVC.modalPresentationStyle = .Popover sortVC.popoverPresentationController?.sourceRect = filterButton.bounds sortVC.preferredContentSize = CGSizeMake(216, 150) sortVC.popoverPresentationController!.delegate = self } } 

And then use

 func popoverPresentationControllerDidDismissPopover(popoverPresentationController: UIPopoverPresentationController) 

to handle his dismissal.

+13
source share

The popoverControllerDidDismissPopover: method popoverControllerDidDismissPopover: been replaced by popoverPresentationControllerShouldDismissPopover: because the UIPopoverControllerDelegate been replaced by UIPopoverPresentationControllerDelegate .

From your view view controller, compatible with the new protocol and set the delegate for the popover view controller to prepareForSegue: ::

 class MyPresentingViewController: UIViewController, UIPopoverPresentationControllerDelegate { override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { if let popoverPresentationController = segue.destinationViewController.popoverPresentationController { popoverPresentationController.delegate = self } } func popoverPresentationControllerShouldDismissPopover(popoverPresentationController: UIPopoverPresentationController) -> Bool { return true } } 

You can then use the delegate method to handle the dismissal detection as you previously expected.

+7
source share

I found that instead of using delegates that only detect when touched outside the view, if you want to detect all deviations, then I believe that it is best to use the closure that is called in viewWillDisappear (). This way you catch all the layoffs in one place.

 class SecondViewController: UIViewController { var leaveAction: (() -> Void)? override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) leaveAction?() } } 
 class FirstViewController: UIViewController { private var isShowingPopover = false // ... override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "popoverSegue" { let vc = segue.destinationViewController isShowingPopover = true vc.leaveAction = { [weak self] in // Gets called when leaveAction?() is called in SecondViewController self?.isShowingPopover = false } vc.modalPresentationStyle = .popover vc.popoverPresentationController?.sourceRect = filterButton.bounds vc.preferredContentSize = CGSizeMake(216, 150) vc.popoverPresentationController!.delegate = self } } } // MARK: - Popover delegates extension FirstViewController: UIPopoverPresentationControllerDelegate { func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle { return .none } func popoverPresentationControllerShouldDismissPopover(_ popoverPresentationController: UIPopoverPresentationController) -> Bool { return true } } 
0
source share

All Articles