How to reload tableview from another view controller in swift
Asked Answered
V

6

39

When I dismiss a modal view controller I want the tableview to update, I am using the form sheet presentation style on iPad so the viewWillAppear and the viewDidAppear methods will not work

Vasiliki answered 18/9, 2014 at 20:18 Comment(2)
You can use NSNotificationCenter to fire a method that update your tableview.Morgan
Can u show me how, im not very familiar with NSNotificationCenter thanksVasiliki
M
100

You can do this:

In your tableView Controller:

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(loadList), name: NSNotification.Name(rawValue: "load"), object: nil)
}
 
@objc func loadList(notification: NSNotification){
    //load data here
    self.tableView.reloadData()
}

Then in the other ViewController :

NotificationCenter.default.post(name: NSNotification.Name(rawValue: "load"), object: nil)
Morgan answered 18/9, 2014 at 20:33 Comment(6)
This isn't working for me for some reason. I added a breakpoint at the line //load data here but the table view doesn't show the new data addedNeu
Thanks, this perfect solution, I was looking for some thing like this.Homestead
Worked for Me, I even called the postNotificationName function from a separate class, not even a viewcontrollerBismuth
@ZackShapiro try to set that dispatch_async(dispatch_get_main_queue(), { self.tableView.reloadData() }); rather than self.tableView.reloadData() , it worked for meSimilar
This answer should be marked, it works, it's clean and understandable.Harvard
Perfectly!! I'm searching a way to reload like 3 tableView's data in 3 VC from other VC. Now I could sync the data in which is not current active VC. Thanks, bro.Senseless
B
51

Swift 3 version code: In your first view controller:

override func viewDidLoad() {
        super.viewDidLoad()
        NotificationCenter.default.addObserver(self, selector: #selector(loadList), name: NSNotification.Name(rawValue: "load"), object: nil)
    }

func loadList(){
        //load data here
        self.tableView.reloadData()
    }

In your second view controller:

NotificationCenter.default.post(name: NSNotification.Name(rawValue: "load"), object: nil)
Battat answered 18/2, 2017 at 15:47 Comment(3)
where in the second VC?Glasgo
Anywhere in your second view controller where you think it's time to update the tableView possibilities are: methods, viewDidLoad or with in any part of code.. Hope its helpfulBattat
great, lifesaver solution!Cretan
B
2

Missing comma on this line, should instead be:

NSNotificationCenter.defaultCenter().addObserver(self, selector: "loadList:", name:"load", object: nil)
Burdock answered 7/11, 2014 at 1:8 Comment(0)
G
2

I find the segue approach more elegant.

Let's say that we have ViewControllerA and a ViewControllerB. We are at ViewControllerB and we want from ViewControllerB to jump straight back to ViewControllerA and update the table view in ViewControllerA.

In ViewControllerA add the following action in your ViewController class:

@IBAction func unwindToViewControllerA(segue: UIStoryboardSegue) {
    DispatchQueue.global(qos: .userInitiated).async {
        DispatchQueue.main.async {
            self.tableView.reloadData()
        }
    }
}

Yes, this code goes in the ViewController of the ViewController you want to go back to!

Now, you need to create an exit segue from the ViewControllerB's storyboard (StoryboardB). Go ahead and open StoryboardB and select the storyboard. Hold CTRL down and drag to exit as follows:

enter image description here

You will be given a list of segues to choose from including the one we just created:

enter image description here

You should now have a segue, click on it:

enter image description here

Go in the inspector and set a unique id: enter image description here

In the ViewControllerB at the point where you want to dismiss and return back to ViewControllerA, do the following (with the id we set in the inspector previously):

self.performSegue(withIdentifier: "yourIdHere", sender: self)

Now, whenever you use the segue to return back to ViewControllerA, the ViewControllerA will update the TableView straightaway.

Groome answered 18/5, 2019 at 16:20 Comment(0)
V
1

An alternate solution: override UIViewController's dismiss(animated:completion:) method on the view controller that manages the table view (and presents the other one modally), so you can reload the table then:

override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
    super.dismiss(animated: flag, completion: completion)

    self.tableView.reloadData()    
}

Note: This should work even if you call dismiss(animated:completion:) on the modal view controller itself (a viable alternative), because ultimately the call gets relayed to the presenting view controller.

From the method's docs:

The presenting view controller is responsible for dismissing the view controller it presented. If you call this method on the presented view controller itself, UIKit asks the presenting view controller to handle the dismissal.

(emphasis mine)

Very answered 4/12, 2018 at 7:2 Comment(0)
E
0

You can use NotificationCenter to update your tableview.

First add observer...

NotificationCenter.default.addObserver(self, selector: #selector(doThisWhenNotify(notification:)), name: NSNotification.Name(rawValue: "load"), object: nil)

func doThisWhenNotify(notification : NSNotification) {
    let info = notificatio.userInfo
    //update tableview

}

Post on other ViewController

NotificationCenter.default.post(name: NSNotification.Name(rawValue: "load"), object: nil, userInfo: [String : Any])
Eruct answered 4/12, 2018 at 6:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.