Estoy usando un NSTableView y DifferenceKit. Todo esto es programático, sin Interface Builder en absoluto.
Anteriormente implementé solo tableView(_:objectValueFor:row)
para obtener valores en mi tabla. En ese momento pude aplicar recargas completas y parciales y todo funcionó bien.
Ahora agregué una implementación de tableView(_:viewFor:row:)
para formatear algunas columnas de manera diferente, y se ve afectada la recarga. Un reloadData()
completo aún funciona, pero una llamada a reloadData(forRowIndexes:columnIndexes)
no llama ni a mi fuente de datos ni a los métodos delegados; la recarga parece simplemente desaparecer.
También intenté eliminar el método de fuente de datos y ejecutar solo con tableView(_:viewFor:row:)
pero sin dados. Una recarga parcial todavía no llama al método de delegado.
¿Se ha topado alguien con esto? ¿Hay algún matiz de NSTableView que me estoy perdiendo?
Mi código (truncado):
init() { ... tableView.dataSource = self tableView.delegate = self columns.forEach { tableView.addTableColumn($0) } } func tableView( _ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int ) -> Any? { ... return someStringProvider(column, row) } func tableView( _ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int ) -> NSView? { ... if let existingView = tableView.makeView(withIdentifier: identifier, owner: self) as? NSTableCellView { existingView.textField?.stringValue = someStringProvider(column, row) return existingView } let textField = NSTextField() ... textField.stringValue = someStringProvider(column, row) let view = NSTableCellView() view.identifier = identifier view.addSubview(textField) view.textField = textField view.addConstraints([ ... (pin textField to view) ]) textField.bind( .value, to: view, withKeyPath: "objectValue", options: nil ) return view }
Esto resulta ser un malentendido, o posiblemente un error, en la forma en que DifferenceKit interactúa con un NSTableView basado en vistas, en lugar de en celdas.
De manera crucial, no estaba verificando los valores con los que se llamó a reloadData(forRowIndexes:columnIndexes)
, y los índices de columna pasados por el algoritmo de DifferenceKit siempre fueron [0]
, que no era válido para ninguna celda visible ya que mi primera columna está oculta, por lo que los métodos no fueron no ha llamado
La lección útil aquí es que cuando el delegado de una vista de tabla carece de tableView(_:viewFor:row:)
, una recarga en cualquier columna recarga la fila completa, pero una vez que se especifican las vistas, los valores de la columna se vuelven relevantes.