Maysam Maysam - 4 months ago 115
Swift Question

Swift: Popover dismiss callback

There are two UIViewConrollers in my Storyboard: MainViewController and SecondViewController. I'm going to show SecondViewController as a popover when user taps a button called Show Popover:

enter image description here

//MainViewController
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{

if segue.identifier == "GoToSecondViewControllerSegue"
{
var vc = segue.destinationViewController as! SecondViewController
var controller = vc.popoverPresentationController

if controller != nil
{
controller?.delegate = self
vc.inputTextDelegate = "I'm a popover!"
}
}
}

func popoverPresentationControllerDidDismissPopover(popoverPresentationController: UIPopoverPresentationController) {
println("done")
}

func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle
{
return .None
}





//SecondViewController
@IBAction func dismissPopover(sender: UIButton) {
dismissViewControllerAnimated(true, completion: nil)
//This dismisses the popover but does not notify the MainViewConroller
}


The anchor of segue is connected to a button:
enter image description here

Now I have two problems:


  1. When I tap the cancel button inside the popover it dismisses the popover but does not trigger
    popoverPresentationControllerDidDismissPopover
    inside the MainViewController

  2. How can I pass data from the SecondViewController to the MainViewController, text value of a UITextView for example.


Answer

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)
 }

}