关闭弹出窗口后如何调用函数?

How to call a function after closing a popover?

希望有人能给初学者一些指导,我的问题是这样的:

我有一个弹出窗口 window 我用来自 mainViewController 的 segue 打开那个 popover 我想在弹出窗口关闭时在 mainViewController 中触发一个函数 在弹出窗口中,我有一个按钮可以使用以下代码关闭弹出窗口:

@IBAction func closeButton(_ sender: Any) {

        dismiss(animated: true, completion: {checkIfPopoverDismissed()}) // I want to trigger this function in the mainView
    }

在 mainViewController 中我有以下函数,我想通过关闭上面的弹出框来触发

 func checkIfPopoverDismissed()
    {
      print("the function is triggered")
    }

所以通过以上我得到:

 Use of unresolved identifier 'checkIfPopoverDismissed'

因为很明显 checkIfPopoverDismissed() 在 mainViewController 中,在 popover 视图中不存在。

知道如何让这项工作变得简单吗?

最好的方法是在 MainViewControllerviewWillAppear 中调用它。方法如下:

class MainViewController: UIViewController {
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        checkIfPopoverDismissed()
    }
}

注意:如果您不希望每次 MainViewController 出现时都调用它,那么您可以检查弹出窗口何时出现,并在出现弹出窗口时切换它并调用它只有在条件满足时才起作用。以下是实现此目标的方法:

class ViewController: UIViewController {
    var isPopoverPresented = false
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        if isPopoverPresented {
            isPopoverPresented.toggle()
            checkIfPopoverDismissed()
        }
    }
    func presentPopover() {
        isPopoverPresented.toggle()
        present(PopoverController(), animated: true)
    }
}

理想情况下,您应该编写一个委托来调用从警报或弹出视图控制器到主视图控制器的方法。

代码示例如下:

// Create a protocol with set of methods
protocol AlertVCDelegate: class {
    func checkIfPopoverDismissed()
}

class AlertVC: UIViewController {
    // Create var to hold the delegate
    // Make it weak to avoid reference cycle
    weak var delegate: AlertVCDelegate!

    @IBAction func closeButton(_ sender: Any) {

        dismiss(animated: true, completion: {
            // Trigger the function on the main view controller
            // through delegation
            self.delegate.checkIfPopoverDismissed()
        })
    }
}

// Conform to the Alert delegte
class MainViewController: UIViewController, AlertVCDelegate {
    let alertControllerObj = AlertVC()

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        // Set the delegate
        // Not necessary to do it from viewWillAppear
        // Set the delegate wherever you create a instance for pop-over
        alertControllerObj.delegate = self
    }

   // Implement the method defined in the protocol
   func checkIfPopoverDismissed()
   {
     print("the function is triggered")
   }
}

因为你是初学者,如果你想了解更多关于代表的信息,这里有一个简单易懂的博客: https://medium.com/@astitv96/passing-data-between-view-controllers-using-delegate-and-protocol-ios-swift-4-beginners-e32828862d3f

*试试这个:

class MainViewController:UIViewController{

      /*In your mainViewController create an instance(I assume the name of the 
      class, you can change this accordingly)*/

     //Create a shared instance of mainVC

   static var sharedInstance:MainViewController?

   // in viewDidLoad() assign the property to self

   override func viewDidLoad() {
    super.viewDidLoad()
     MainViewController.sharedInstance = self
} 
  func checkIfPopoverDismissed()
    {
      print("the function is triggered")
    }

}


 //Assuming the class name
class PopOverView:UIViewController{

  @IBAction func closeButton(_ sender: Any) {

  dismiss(self,animated: true, completion: 
   {MainViewController.sharedInstance?.checkIfPopoverDismissed()})

    }

您可以使用委托来实现:

// 1. create a protocol before your PopoverViewController:
// (imagine the delegate is your helper and the protocol is the requirement of your helper)

protocol PopoverViewControllerDelegate: class {
    func popoverDidDismissed()
}

class PopoverViewController: UIViewController {
    //2. make a delegate in your view controller
    //(you need a this helper in your class to help you...)
    weak var delegate: PopoverViewControllerDelegate?


    //...

    @IBAction func closeButton(_ sender: Any) {
        //3. ask the delegate to perform its function
        //(when the time is right, ask you helper to do what he is meant to do...)
        dismiss(
            animated: true, 
            completion: delegate?.popoverDidDismissed
        )
    }
}

同时在 mainViewController 中...

class mainViewController: UIViewController {
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let destinationVC = segue.destination as? PopoverViewController {
            //4. setup the delegation
            //(say that I (mainViewController) will be the helper of destinationVC)
            destinationVC.delegate = self
        }
    }
}

//5. Conform the protocol
//(need to meet the requirement as this helper, by having a function called popoverDidDismissed...)

extension mainViewController: PopoverViewControllerDelegate {
    func popoverDidDismissed() {
        // do what you want to do here in the main view controller,
        // this function will be called by PopoverViewController when the time is right
    }
}

您需要的是展开转场。一个似乎经常被忽略的功能。

在此处查看官方文档: https://developer.apple.com/documentation/uikit/resource_management/dismissing_a_view_controller_with_an_unwind_segue

链接页面没有显示的是,您还可以通过控制从 "View Controller" 图标直接拖动到 "Exit" 图标来创建一个手动转场,您可以根据需要从代码中调用先做一些验证。

在上面的例子中,unwindHere在主视图控制器中被定义为:

@IBAction func unwindHere(unwindSegue: UIStoryboardSegue) {
    if let sourceVC = unwindSegue.source as? PopoverViewController {
        // Do stuff
    }
}

编辑:您在 PopoverViewController 中使用的操作可能如下所示:

@IBAction func closeButtonTapped(_ sender: UIButton) {
    performSegue(withIdentifier: "ExitPopover", sender: self)
}

这里,"ExitPopover"是unwind segue的标识符。