Swift: Popover dismiss callback

后端 未结 4 1606
太阳男子
太阳男子 2020-12-30 10:56

There are two UIViewConrollers in my Storyboard: MainViewController and SecondViewController. I\'m going to show S

相关标签:
4条回答
  • 2020-12-30 11:02

    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")
        }
    
    }
    
    0 讨论(0)
  • 2020-12-30 11:09

    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)
     }
    
    }
    
    0 讨论(0)
  • 2020-12-30 11:15

    Or, more simply, just call iOS's delegate method manually when you dismiss the popover manually.

        dismissViewControllerAnimated(true, completion: nil)
        popoverPresentationController?.delegate?.popoverPresentationControllerDidDismissPopover?(popoverPresentationController!)
    
    0 讨论(0)
  • 2020-12-30 11:22

    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.

    0 讨论(0)
提交回复
热议问题