【问题标题】:call a function of a maincontroller after a presented viewcontroller is dismissed关闭呈现的视图控制器后调用主控制器的函数
【发布时间】:2018-04-26 15:04:34
【问题描述】:

我有一个显示视图控制器的 MainViewcontroller。用户可能会采取一个动作,首先应该关闭视图控制器,然后调用 MainViewcontroller 中定义的函数。

约束是这个函数将创建一个新的vc来呈现。我试过主控制器的viewWillAppear和viewdidAppear。这不起作用,因为它们被多次调用。

我也可以使用通知机制,但我不确定 MainViewController 是否会在收到通知之前出现。

【问题讨论】:

  • viewWillAppear/viewDidAppear第一次运行后使用布尔值来检测是否应该调用该函数并将其设置为false。

标签: ios swift


【解决方案1】:

你应该看看presentingViewController document。从呈现的视图控制器中,您可以使用 self.presentingViewController 获取 MainViewController。在下面试试我的代码

let mainViewController = self.presentingViewController as! MainViewController

self.dismiss(animated: true) {
  mainViewController.doWhateverYouWant()
}

【讨论】:

  • 这样做,确定执行闭包时mainViewController是可见的吗?
  • 关闭将在视图控制器关闭后执行。这时候,mainViewController 是可见的。你可以试试看。
  • 你的代码在打开一个可选参数时意外抛出了 nil
  • 更新了我的答案,你可以再试一次。
  • 我认为应该在要捕获的闭包之外定义mainviewcontroller。
【解决方案2】:

具体解决方案

假设这是你的MainViewController

class MainViewController: UIViewController {

    func foo() {
        print("foo")
    }    
}

你可以像这样声明你的SecondViewController

class SecondViewController: UIViewController {

    @IBAction func didTapDismiss(_ sender: UIButton) {
        self.dismiss(animated: true, completion: nil)
    }

    override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
        let mainViewController = self.presentingViewController as? MainViewController
        super.dismiss(animated: flag) {
            mainViewController?.foo()
            completion?()
        }
    }
}

如您所见,一旦 SecondViewController 被解除,mainViewController?.foo() 方法就会被调用。

一般解决方案

让我们定义MainViewController

class MainViewController: UIViewController {

    typealias CallBack = () -> Void

    func foo() {
        print("foo")
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let mainViewControllerCallbackProtocol = segue.destination as? MainViewControllerCallbackProtocol {
            mainViewControllerCallbackProtocol.mainViewControllerCallback = { [weak self] in
                self?.foo()
            }
        }
    }
}

还有自己的回调协议

protocol MainViewControllerCallbackProtocol:AnyObject {
    var mainViewControllerCallback: MainViewController.CallBack? { get set }
}

最后让我们将SecondViewController 统一为MainViewControllerCallbackProtocol

class SecondViewController: UIViewController, MainViewControllerCallbackProtocol {

    var mainViewControllerCallback: MainViewController.CallBack?

    @IBAction func didTapDismiss(_ sender: UIButton) {
        self.dismiss(animated: true, completion: nil)
    }

    override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
        super.dismiss(animated: flag) { [weak self] in
            self?.mainViewControllerCallback?()
            completion?()
        }
    }
}

【讨论】:

    猜你喜欢
    • 2017-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-09
    • 1970-01-01
    相关资源
    最近更新 更多