【问题标题】:Swift: Popover dismiss callbackSwift:弹出框关闭回调
【发布时间】:2015-08-12 13:36:56
【问题描述】:

我的 Storyboard 中有两个 UIViewConrollersMainViewControllerSecondViewController。当用户点击一个名为 Show Popover 的按钮时,我将把 SecondViewController 显示为一个弹出框:

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

segue 的锚点连接到一个按钮:

现在我有两个问题:

  1. 当我点击弹出框内的取消按钮时,它会关闭弹出框,但不会触发 MainViewController

  2. 内的popoverPresentationControllerDidDismissPopover
  3. 如何将数据从 SecondViewController 传递到 MainViewController,例如 UITextView 的文本值。

【问题讨论】:

    标签: swift uipopovercontroller


    【解决方案1】:

    或者,更简单地说,当您手动关闭弹出框时,只需手动调用 iOS 的委托方法。

        dismissViewControllerAnimated(true, completion: nil)
        popoverPresentationController?.delegate?.popoverPresentationControllerDidDismissPopover?(popoverPresentationController!)
    

    【讨论】:

    • 以编程方式完成几乎所有事情时最简单的解决方案
    • 一个按预期工作的简单衬里。谢谢卢克!
    【解决方案2】:

    您需要将自己设置为 popOverDelegate。您必须在目标的 popoverPresentationController 中执行此操作。

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        segue.destination.popoverPresentationController?.delegate = self
    }
    

    然后在你的 ViewController 中声明实现委托:

    extension FormViewController: UIPopoverPresentationControllerDelegate {
    
        func popoverPresentationControllerDidDismissPopover(_ popoverPresentationController: UIPopoverPresentationController) {
            printBreadcrumb("Dismissed popover")
        }
    
    }
    

    【讨论】:

    • popoverPresentationControllerDidDismissPopover 自 iOS 13 起已弃用,并已替换为 presentationControllerDidDismiss
    【解决方案3】:

    协议和授权是解决此类问题的方法。在我的例子中,我定义了一个协议并使 MainViewController 符合该协议。

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

    【讨论】:

    • 您需要将自己设置为代理。看我的回答。
    【解决方案4】:

    我也有同样的问题,在Apple API找到答案。

    关于函数popoverPresentationControllerDidDismissPopover,他们说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.

    所以我们必须自己做。

    您可以选择像 @Maysam 那样更重的块或委托。 这是我使用块的方式仅供参考。

    让我们只关注关键功能。

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

    我做了一个块,称之为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)
     }
    
    }
    

    在 prepareForSegue: 方法中设置块,然后完成。

    【讨论】:

      猜你喜欢
      • 2014-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-06
      • 2016-03-30
      • 2017-09-14
      • 1970-01-01
      相关资源
      最近更新 更多