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

Posted

技术标签:

【中文标题】关闭弹出框后如何调用函数?【英文标题】:How to call a function after closing a popover? 【发布时间】:2020-06-01 02:47:01 【问题描述】:

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

我有一个弹出窗口 我用 mainViewController 的 segue 打开那个弹出窗口 我想在弹出窗口关闭时触发 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 视图中不存在。

知道如何简单地完成这项工作吗?

【问题讨论】:

我相信你需要在闭包中使用'self'来让闭包知道 checkIfPopoverDismissed 来自哪里。 【参考方案1】:

您可以使用委托来实现:

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

【讨论】:

谢谢你,这就是它最终工作的原因。现在我要努力学习它的工作原理! 不客气。委托模式对于使用 swift 的 ios 应用程序开发非常重要。如果一切正常,请接受这个答案,如果有任何问题,请告诉我。祝你好运:)【参考方案2】:

*试试这个:

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())

    

【讨论】:

【参考方案3】:

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

下面是代码示例:

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

【讨论】:

【参考方案4】:

最好的方法是在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)
    

【讨论】:

【参考方案5】:

你需要的是一个放松的转场。一个似乎经常被忽略的功能。

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

链接页面没有显示的是,您还可以从“View Controller”图标直接拖动到“Exit”图标以创建手动segue,如果您想先进行一些验证,您可以从代码中调用.

在上面的例子中,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”是展开转场的标识符。

【讨论】:

以上是关于关闭弹出框后如何调用函数?的主要内容,如果未能解决你的问题,请参考以下文章

关闭弹出框后表格视图没有更新?

关闭导航弹出框后,共享 iAd 横幅会卸载广告

实现网页弹出框后背景不能滑动的效果

系统关闭后仍在调用$modal控制器的作用域函数。

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

修改ios自有的上传弹出框样式vue