Su_toL
Su_toL

Reputation: 167

UITabBarController does not load Custom UITableView

I'm having a weird issue with my UITableView loading within my UITabBarController. When I initially transition to the TabBar view (from a "login" view controller), the Table does not load/display its data. It is only after I click between on a different tab, then back to the original tab that it will then load the information. The data for the table is being retrieved from a server, which happens in a function that runs both in viewDidLoad and viewWillAppear for the relevant tab.

I'm not entirely sure why this is happening. The code below are the viewDidLoad and viewWillAppear functions for the tab housing the tableView. Any tips are appreciated. Thanks.

override func viewDidLoad() {
    super.viewDidLoad()

    getTableInfo()
    tableView.allowsSelection = false
    tableView.delegate = self
    tableView.dataSource = self
    tableView.reloadData()
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    getTableInfo()
    tableView.reloadData()
}

EDIT: The below is the code used to get the information from the server for the table, into a variable tableInfo:

let task = URLSession.shared.dataTask(with: request) { data, response, error in
            let httpResponse = response as! HTTPURLResponse
            let statusCode = httpResponse.statusCode
            if (statusCode == 200) {
                do {
                    if let data = data,
                        let jsonResponse = try JSONSerialization.jsonObject(with: data) as? [String: Any] {
                        self.tableView.removeAll()
                        if let locations = jsonResponse["pictures"] as? String {
                            self.tableInfo = locations.lines
                            self.tableInfo.reverse()
                        }
                    }
                } catch {
                    print("Error deserializing JSON: \(error)")
                }
            }

There are checks for other status codes that I omitted as they are irrelevant (they just display an alert box describing an error if triggered).

Upvotes: 0

Views: 193

Answers (2)

kwam
kwam

Reputation: 1

Had the same thing happen to me with a project I'm working on. My tableView wouldn't show the data I had loaded from Firebase in the TabBarController class of my project. Fixed it by moving the code from that class to the ViewController that held the tableview. And in the code that retrieved the data from Firebase, I called reloadData() after appending each child from the server into my data array. - Hope this fix works for you too mate!

Upvotes: 0

t4nhpt
t4nhpt

Reputation: 5302

The getTableInfomethod is asynchronized, so when you call tableView.reloadData(), the self.tableInfo still empty. It is just filled with data after the async method is completed.

So, to fix it, you just need to call tableView.reloadData() after you set data to the self.tableInfo variable.

if let locations = jsonResponse["pictures"] as? String {
                        self.tableInfo = locations.lines
                        self.tableInfo.reverse()
                        self.tableView.reloadData()
                    }

For carefully coding in this case, you may need to create a weak self in the closure to prevent keep this class instance. And you also need to reload table view in main thead.

let task = URLSession.shared.dataTask(with: request) { [weak self] data, response, error in
        guard let `self` = self else { return }

        let httpResponse = response as! HTTPURLResponse
        let statusCode = httpResponse.statusCode
        if (statusCode == 200) {
            do {
                if let data = data,
                    let jsonResponse = try JSONSerialization.jsonObject(with: data) as? [String: Any] {
                    self.tableView.removeAll()
                    if let locations = jsonResponse["pictures"] as? String {
                        self.tableInfo = locations.lines
                        self.tableInfo.reverse()
                        DispatchQueue.main.async(execute: { 
                            self.tableView.reloadData()
                        })

                    }
                }
            } catch {
                print("Error deserializing JSON: \(error)")
            }
        }

Upvotes: 1

Related Questions