A O A O - 23 days ago 8
Swift Question

Some TableView views are not reloading, as my TableView Delegate is not receiving tableView:viewFor:row: for every row

I have a

TableView
, and a
TableViewController


The
TableView's
delegate
and
datasource
are set to the
TableViewController


So when the table goes to draw, it asks the delegate for the views, and this code runs:

func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {

let result = tableView.make(withIdentifier: "flagView", owner: self) as? TableCellView

case "technicalFlag", "supplyFlag":
let button = result?.control as? NSButton {
button.state = value.boolValue ? NSOnState : NSOffState
}
}


Which updates the buttons properly:

enter image description here

Notice how there are 5 flags for Technical Risk

However, when I go to sort by Supply Risk, it calls
tableView.reloadData()


But, not every view gets reloaded?

As a result, some of the flags stay black, even when they shouldn't be (notice 8+ black flags in Technical Risk, now)

enter image description here

It's seemingly random which flags are black (when I look at the data via another view via context menu, I can tell which flags should truly be black)

So ostensibly, it looks like a redrawing issue. I've tried everything, but can't get those views to redraw. Am I missing something?

I've confirmed that
tableView:viewFor:row:
is just not getting called as many times as I think it should

I guess, to sum things up, I thought that calling
reloadData()
would update every view at every row x column? How does the runtime decide which views get the update call?

A O A O
Answer Source

Ah solved it, I had modified the original code because I didn't think it was relevant to show:

    case "technicalRiskFlag", "supplyRisk":
        if let value = node.value(forKeyPath: identifier) as? NSNumber,
        let button = result?.control as? NSButton {
            button.state = value.boolValue ? NSOnState : NSOffState
        }

But turns out that value could be nil, which ended up not redrawing the flag. Not sure why the delegate method didn't get called still, but I changed the code to this:

        if let button = result?.control as? NSButton {
            if let value = node.value(forKeyPath: identifier) as? NSNumber {
                button.state = value.boolValue ? NSOnState : NSOffState
            } else {
                button.state = NSOffState
            }
        }

and it works perfect now