There are two UIViewConrollers in my Storyboard: MainViewController and SecondViewController. I\'m going to show S
You need to set yourself as the popOverDelegate. You have to do this in the popoverPresentationController of the destination.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
segue.destination.popoverPresentationController?.delegate = self
}
Then declare implement the delegates in your ViewController:
extension FormViewController: UIPopoverPresentationControllerDelegate {
func popoverPresentationControllerDidDismissPopover(_ popoverPresentationController: UIPopoverPresentationController) {
printBreadcrumb("Dismissed popover")
}
}
Protocols and delegations are solution to such problems. In my case I defined a protocol and conformed the MainViewController to the protocol.
//SecondViewController
protocol MyDelegate{
func DoSomething(text:String)
}
class SecondViewController: UIViewController {
var delegate:GetTextDelegate?
var inputTextDelegate:String = ""
override func viewDidLoad() {
newText.text = inputTextDelegate
}
@IBAction func dismissPopover(sender: UIButton) {
dismissViewControllerAnimated(true, completion: nil)
//This dismisses the popover but does not notify the MainViewConroller
}
@IBAction func doneButtonAction(sender: UIButton) {
if let delegate = self.delegate {
delegate.DoSomething(newText.text)
self.dismissViewControllerAnimated(true, completion: nil)
}
}
}
class MainViewController: UIViewController, UIPopoverPresentationControllerDelegate, MyDelegate {
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
if segue.identifier == "GoToSecondViewControllerSegue"
{
var vc = segue.destinationViewController as! SecondViewController
vc.delegate = self
vc.inputTextDelegate = "I'm a popover!"
}
}
func popoverPresentationControllerDidDismissPopover(popoverPresentationController: UIPopoverPresentationController) {
//...
}
func DoSomething(text: String) {
//Do whatever you want
println(text)
}
}
Or, more simply, just call iOS's delegate method manually when you dismiss the popover manually.
dismissViewControllerAnimated(true, completion: nil)
popoverPresentationController?.delegate?.popoverPresentationControllerDidDismissPopover?(popoverPresentationController!)
I have the same problem and find the answer in Apple API.
About the function popoverPresentationControllerDidDismissPopover
, they say The popover presentation controller calls this method after dismissing the popover to let you know that it is no longer onscreen. The presentation controller calls this method only in response to user actions. It does not call this method if you dismiss the popover programmatically.
So we have to do it ourselves.
You can choice a block or a delegate like @Maysam did which is more heavy. Here's my way to use a block FYI.
Let's just focus on key functions.
class SecondViewController: UIViewController {
var dismissPopover: (() -> Void)?
deinit {
if let block = self.dismissPopover {
block()
}
}
@IBAction func dismissPopover(sender: UIButton) {
dismissViewControllerAnimated(true, completion: nil)
//This dismisses the popover but does not notify the MainViewConroller
}
}
I made a block, and call it well secondVC deinit.
class MainViewController: UIViewController, UIPopoverPresentationControllerDelegate, MyDelegate {
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
if segue.identifier == "GoToSecondViewControllerSegue"
{
var vc = segue.destinationViewController as! SecondViewController
vc..dismissPopover = {
[unowned self] () in
self.DoSomehing()
// call your method...
}
}
}
func DoSomething(text: String) {
//Do whatever you want
println(text)
}
}
Set up the block in prepareForSegue: method, and Done.