【问题标题】:How do I refresh ViewController after dismiss method is called调用dismiss方法后如何刷新ViewController
【发布时间】:2025-12-06 15:05:01
【问题描述】:

例如,我有两个名为 A 和 B 的 viewController。在调用 present 方法后,我移动到“B 视图控制器”。我通过“B viewController”上的 UserDefaults.stnadard 设置了一些值,并在调用解除方法后返回“A 视图控制器”。 “A viewController”必须显示修改后的值,但它不显示修改后的值。我尝试在“A viewController”上调用viewDidAppear() 方法,但没有成功。我试过调用viewDidLoad()方法,效果很好,但是听说直接调用方法不是很好。系统只能调用它。所以,我不想自己称呼它。我应该如何刷新“A view controller”?

【问题讨论】:

    标签: swift xcode


    【解决方案1】:

    从 iOS 13.0 及更高版本开始,Apple 更改了默认显示 viewController 的方式。所以,ViewControllerA 中的 viewWillAppear 在关闭 ViewControllerB 后不会被调用。

    确保在关闭 ViewControllerB 后调用 viewWillAppear 方法的一种方法是将 viewController 设置 modalPresentationStyle 呈现为 fullScreen 为:

    let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(identifier: "ViewControllerB") as! ViewControllerB
    vc.modalPresentationStyle = .fullScreen
    self.present(vc, animated: true, completion: nil)
    

    示例代码:

    ViewControllerA.swift

    class ViewControllerA: UIViewController {
    
        private var username: String? {
            UserDefaults.standard.string(forKey: "USERNAME")
        }
    
        override func viewDidLoad() {
            super.viewDidLoad()
        }
    
        override func viewWillAppear(_ animated: Bool) {
            super.viewWillAppear(animated)
            print(username) //set this to desired view
        }
    
        @IBAction func goToViewControllerB(_ sender: UIButton) {
            let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(identifier: "ViewControllerB") as! ViewControllerB
            vc.modalPresentationStyle = .fullScreen
            self.present(vc, animated: true, completion: nil)
        }
    }
    

    ViewControllerB.swift

    class ViewControllerB: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            UserDefaults.standard.set("John", forKey: "USERNAME")
        }
    
        @IBAction func dismiss(_ sender: Any) {
            self.dismiss(animated: true, completion: nil)
        }
    }
    

    如果您不想将 modalPresentationStyle 更改为 fullScreen,那么您可以在关闭 ViewControllerB 时使用闭包将数据传递给 ViewControllerA。

    【讨论】:

    • 1) 非 Swift 也是如此吗? Apple 上哪里讨论过这个问题?
    【解决方案2】:

    我认为 NotificationCenter 或原型会帮助完成这项工作。

    通知中心示例

    class ViewControllerA: UIViewController {
        override func viewDidLoad() {
            super.viewDidLoad()
            NotificationCenter.default.addObserver(self, selector: #selector(testFunc), name: NSNotification.Name(rawValue:  "PeformAfterPresenting"), object: nil)
    
        }
    
        @objc func testFunc() {
          //TODO: your task
        }
    }
    

    类 ViewControllerB: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    @IBAction func dismiss(_ sender: Any) {
    
        NotificationCenter.default.post(name: "PeformAfterPresenting"), object: nil, userInfo: dataDict)
    
            self.dismiss(animated: true, completion: nil)
        }
    }
    

    【讨论】: