Reputation: 167
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
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
Reputation: 5302
The getTableInfo
method 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