Swift:如何以编程方式关闭 ViewController?

Swift: How to dismiss a ViewController programmatically?

我遇到了一个小问题。 在我的主视图控制器上,我有一个打开幻灯片菜单的条形按钮,这是一个使用过渡幻灯片的常规视图控制器。滑动菜单有一个按钮可以打开另一个视图控制器。当新的视图控制器打开时,您可以选择取消,这会关闭当前的视图控制器。问题是,用户再次进入菜单视图,而不是主视图控制器。很高兴知道我做错了什么:)

func openSupport() {
    guard  let creditViewContoller = storyboard?.instantiateViewController(withIdentifier: "support") as? CreditViewController else { return }
    present(creditViewContoller, animated: true)
}

@IBAction func buttonSupport(_ sender: UIButton) {
    let menuView = MenuViewController()
    menuView.dismiss(animated: true, completion: nil)
    openSupport()
    print("Tap on Support")
}

您可以简单地使用

关闭视图控制器
self.dismiss(animated: true, completion: nil)

考虑

@IBAction func buttonSupport(_ sender: UIButton) {
    let menuView = MenuViewController()               // (1)
    menuView.dismiss(animated: true, completion: nil) // (2)
    openSupport()                                     // (3)
    print("Tap on Support")
}

这个:

  1. 创建新的 MenuViewController 但从未展示它;
  2. 在从未出现过的视图控制器上调用 dismiss;和
  3. 从此 MenuViewController 实例调用 openSupport(从未关闭)。

最重要的是,您想让呈现菜单的主视图控制器进行呈现。所以,菜单视图控制器应该:

  1. 为其定义一个协议,通知呈现视图控制器转换到下一个场景:

    protocol MenuViewControllerDelegate: class {
        func menu(_ menu: MenuViewController, present viewController: UIViewController)
    }
    
  2. 然后菜单视图控制器可以在完成关闭后告诉它的委托它应该呈现什么:

    class MenuViewController: UIViewController {
        weak var delegate: MenuViewControllerDelegate?
    
        @IBAction func didTapSupport(_ sender: Any) {
            dismiss(animated: true) {
                guard let controller = self.storyboard?.instantiateViewController(withIdentifier: "support") else { return }
                self.delegate?.menu(self, present: controller)
            }
        }
    
        @IBAction func didTapCancel(_ sender: Any) {
            dismiss(animated: true)
        }
    }
    

然后主视图控制器需要

  1. 确保设置菜单视图控制器的delegate

    class ViewController: UIViewController {
        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            if let destination = segue.destination as? MenuViewController {
                destination.delegate = self
            }
        }
    }
    

  2. 确保显示菜单控制器要求的视图控制器:

    extension ViewController: MenuViewControllerDelegate {
        func menu(_ menu: MenuViewController, present viewController: UIViewController) {
            present(viewController, animated: true)
        }
    }
    

有很多不同的方法可以实现这一点,所以不要迷失在此处的细节中。但想法是要有一些系统,菜单视图控制器可以请求任何人来呈现 support 视图,而不是尝试自己做。