调用dismiss方法后如何刷新ViewController

Posted

技术标签:

【中文标题】调用dismiss方法后如何刷新ViewController【英文标题】:How do I refresh ViewController after dismiss method is called 【发布时间】:2020-02-03 02:49:53 【问题描述】:

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

【问题讨论】:

【参考方案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)
    

【讨论】:

以上是关于调用dismiss方法后如何刷新ViewController的主要内容,如果未能解决你的问题,请参考以下文章

离子 3 警报;调用dismiss()后调用present()不起作用

调用AlertDialog的dismiss方法没有发生任何事情

在 View Dismissal 之前调用 Delegate 方法

在未调用 Popup.open() 的方法中触发 Popup.dismiss() (kivy)

随记Dialog dismiss无法正常关闭问题

随记Dialog dismiss无法正常关闭问题