Search code examples
swiftuipopovercontroller

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.


Solution

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