Swift:弹出框关闭回调

Posted

技术标签:

【中文标题】Swift:弹出框关闭回调【英文标题】:Swift: Popover dismiss callback 【发布时间】: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 的锚点连接到一个按钮:

现在我有两个问题:

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

    内的popoverPresentationControllerDidDismissPopover

    如何将数据从 SecondViewController 传递到 MainViewController,例如 UITextView 的文本值。

【问题讨论】:

【参考方案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: 方法中设置块,然后完成。

【讨论】:

以上是关于Swift:弹出框关闭回调的主要内容,如果未能解决你的问题,请参考以下文章

layui 子弹出框操作成功后, 刷新父弹出框的内容

滚动视图中的 Swift 弹出框

无法居中弹出框 Swift

将弹出框添加到以编程方式添加的 UIBarButtonItem 并将图像添加到相同的弹出框 Swift

Swift 中的滑块弹出框

layui列表点击添加/编辑弹出框,ajax执行完毕layer.msg不执行回调的问题