[SOLVED] How to reload NSTableView data when NSSearchField text changes

Issue

I’m a bit stumped on how to reload a NSTableView’s data upon a searchField’s text changing. I assumed that I needed to filter the array that the tableView uses to populate itself based upon string matching and the call tableView.reloadData() all inside of controlTextDidChange() but when I test the code it doesn’t work. I’m assuming that this will be a pretty simple fix and most of the info I’ve found on this topic has been a bit complicated. So I don’t know how simple or complicated the solution really is

Here is my controlTextDidChange() func:

func controlTextDidChange(_ obj: Notification) {
    noteRecords.filter { $0.title.contains(searchField.stringValue) }
    tableView.reloadData()
}

If someone could please explain how to reload the tableViews data using the filtered array upon the searchField’s text changing that would be very much appreciated. Also if it’s easier to replace the searchField with a plain NSTextField let me know.

Edit

here’s the func that populates the tableView:

func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
    let note = allRecords[row]
    let cellIdentifier = NSUserInterfaceItemIdentifier(rawValue: "NoteInCloudCell")
    
    if tableColumn == tableView.tableColumns[0] {
        let cell = tableView.makeView(withIdentifier: cellIdentifier, owner: nil) as? NoteInCloudCell
        cell?.noteTitle.stringValue = note.title
        cell?.cloudID.stringValue = note.cloudID
        return cell
    }
    else { return nil }
}

Solution

Create a second array of the same type as noteRecords and name it allRecords

Assign the complete set of records to allRecords and use noteRecords as data source array

Replace controlTextDidChange with

func controlTextDidChange(_ obj: Notification) {
    let query = searchField.stringValue
    if query.isEmpty {
        noteRecords = allRecords
    } else {
        noteRecords = allRecords.filter { $0.title.localizedCaseInsensitiveContains(query)
    }
    tableView.reloadData()
}

A more sophisticated way is a diffable data source.

Answered By – vadian

Answer Checked By – Mildred Charles (BugsFixing Admin)

Leave a Reply

Your email address will not be published.