Swift 3 tableView not updating on reloadData()

Chris Bell picture Chris Bell · Mar 4, 2017 · Viewed 9.8k times · Source

I am building a master detail app. I have a sections view controller (VC) which is a child of master VC. Clicking on rows in the sections VC brings up different detail VCs where users complete required information. Once the information in a detail VC is completed I would like to have a checkmark display in the relevant section VC row. FYI selectedProject is a core data object.

I call a notification in the detail VC viewWillDisappear to refresh the sections VC.

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
    let detailCase: String = selectedProject!.section![indexPath.row]
    configureCell(cell, withSectionName: detailCase)
    print("location complete is \(selectedProject!.completeLocation)")
    print("electricity complete is \(selectedProject!.completeElectricity)"
    print(cell.textLabel!.text!)
    print(cell.accessoryType.rawValue)
    return cell
}

func configureCell(_ cell: UITableViewCell, withSectionName sectionName: String) {
        switch sectionName {
        case "Project Details" :
            cell.accessoryType = .checkmark
        case "Location" :
            if selectedProject?.completeLocation == true {
                cell.accessoryType = .checkmark
            }
        case "Electricity Use" :
            if selectedProject?.completeElectricity == true {
                cell.accessoryType = .checkmark
            }
        default :
            cell.accessoryType = .none
        }
        cell.textLabel!.text = sectionName
}

func refreshTable(notification: Notification) -> Void {
    print("Notification ran")
    self.tableView.reloadData()
}

Console:

Notification ran

location complete is true

electricity complete is true

Project Details

3

location complete is true

electricity complete is true

Location

3

location complete is true

electricity complete is true

Electricity Use

3

The 3's = .checkmark

So it appears cellForRowAt knows exactly what it should be doing but then the table is not readily displaying the checkmarks. Instead you either have to click back to the master VC then forward to the sections VC to get the checkmarks displaying, or you have to click different rows in the section VC and the checkmarks will randomly show up.

I've tried calling reloadData in dispatchqueue.main.async with no luck. I tried calling reloadData at different points in the process again without success. I've tried calling tableView.beginUpdates/.endUpdates and reloadSectionData, again without success to get the checkmarks to display.

If I programmatically prompt section VC viewWilDisappear and viewWillAppear in succession, the checkmarks will appear once a different row in sections VC is selected. it "seems" like reloadData() isn't prompting a complete reload of the tableView.

FYI accessory item is set to .none in the storyboard.

Answer

dylanthelion picture dylanthelion · Mar 4, 2017

UI updates need to be called on the main queue. Try this:

DispatchQueue.main.async {
    self.tableView.reloadData()
}