4

I have a common view used when the user opens the app (VC1). With a tab bar controller, I load another view (VC2) that can be used to update data visible in the previous one. When I go back on VC1 (which is stack), it does not reload with updated data.

I have tried to call the viewDidLoad in the viewWillAppear like so...

override func viewWillAppear(_ animated: Bool) {
    viewDidLoad()
}

It works, but it loads over the VC1 still on stack and the user can see the change (not good).

I suppose that to dismiss the VC1 would help, but I haven't found how to dismiss a view when using tab bar controller.

Bastien
  • 117
  • 1
  • 1
  • 7
  • Never call `viewDidLoad` or any of the other view controller lifecycle methods yourself. – rmaddy Oct 05 '17 at 03:05
  • You should create a function to refesh data and call it from viewWillAppear – Puneet Sharma Oct 05 '17 at 03:15
  • make a function that loads the data and call it in both viewWillAppear and ViewDidLoad.Or please provide more information so that i can help more. – Niroj Oct 05 '17 at 03:19

2 Answers2

11

Follow these steps to handle you view load setup every time your view will appear:
(VC1 = First View Controller)

  • Create a new function/method (named viewLoadSetup) in your VC1 and move all codes from viewDidLoad() to viewLoadSetup().
  • Now, Call viewLoadSetup() from viewWillAppear

    class VC1: UIViewController {
    
        override func viewDidLoad() {
           super.viewDidLoad()
           // viewLoadSetup()  you may call it from view did load also
        }
    
        override func viewWillAppear(_ animated: Bool) {
           super.viewWillAppear(animated)
           viewLoadSetup()
    
        }
    
    
         func viewLoadSetup(){
          // setup view did load here
         }
    
    
    }
    


If you want to call viewLoadSetup from viewDidLoad for one time, when your view controller is loaded, and then after every time from your viewWillAppear then,

class VC1: UIViewController {

    var isLoadingViewController = false

    override func viewDidLoad() {
        super.viewDidLoad()
        isLoadingViewController = true
        viewLoadSetup()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        if isLoadingViewController {
            isLoadingViewController = false
        } else {
            viewLoadSetup()
         }
    }


    func viewLoadSetup(){
      // setup view did load here
    }


}
Krunal
  • 77,632
  • 48
  • 245
  • 261
  • Thanks @Krunal, now the view is loading. But I still have the problem of the previous version of the VC1. When, in VC2, the user tap on the icon of the tab bar controller, the VC1 shows instantly and he can see old data and animation going over the previous version of VC1. Do you know how to dismiss the VC1 before reloading? I have tried ` self.presentedViewController?.dismiss(animated: true, completion: nil) ` without success. Thanks again. – Bastien Oct 05 '17 at 04:33
  • for `animation going over the previous version of VC1. Do you know how to dismiss the VC1 before reloading?` Use viewDidAppear for animation. – Krunal Oct 05 '17 at 04:53
  • for `the previous version of the VC1. When, in VC2, the user tap on the icon of the tab bar controller, the VC1 shows instantly and he can see old data` hide your view in `viewWillAppear` and again unhide upon data reload finish. Share your view controller code structure. so I can help you better – Krunal Oct 05 '17 at 04:55
1

You could use block in VC2 to call back VC1 to reload something.
First, in VC2, declare a block:

class View2Controller: UIViewController {

    public var completionHandler:(()->Void)?
    //...
}

Second, make callback in VC2 before going back:

self.completionHandler?()

Finally, in VC1, you are able to be called back to reload:

let vc2 = View2Controller()
vc2.completionHandler = { [weak self] () -> Void in
    //call reloading method like: self?.reloadData()
}
Yun CHEN
  • 6,450
  • 3
  • 30
  • 33