For example, I have two viewControllers named A and B. I move to "B view controller" after present method is called. I set some values through UserDefaults.stnadard on "B viewController", and I come back to "A view controller" after dismiss method is called. "A viewController" have to show modified values, but it doesn't show the modified ones. I tried calling viewDidAppear()
method on "A viewController", but it didn't work. I tried calling viewDidLoad()
method, and it worked well, but I heard that it's not a good way to call the method directly. System can only call it. So, I don't want to call it myself. How should I refresh "A view controller"?
From iOS 13.0 and above, Apple has changed the way viewControllers are presented by default. So, viewWillAppear in ViewControllerA will not be called after dimissing ViewControllerB.
One way for making sure the viewWillAppear method will be called after dismissing ViewControllerB is presenting the viewController setting modalPresentationStyle to fullScreen as:
let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(identifier: "ViewControllerB") as! ViewControllerB
vc.modalPresentationStyle = .fullScreen
self.present(vc, animated: true, completion: nil)
Sample Code:
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)
}
}
If you don't want to change the modalPresentationStyle to fullScreen then you can use closures for passing data to ViewControllerA when you're dismissing ViewControllerB.
I think NotificationCenter or prototype would help get this done.
NotificationCenter example
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
}
}
class 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)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With