Search code examples
objective-ccocoanstableviewnsarraycontrollerselectedindex

How to identify an row object in a NSTableView with a specific index?


I use an NSArrayController in InterfaceBuilder to manage objects displayed in am NSTableView. When I selected one or multiple rows the following code gets called to delete the object(s) and update the selection.

NSIndexSet* selectedRowIndices = [m_tableView selectedRowIndexes];
if (!selectedRowIndices || selectedRowIndices.count < 1) {
    return;
}
[self removeObjectsAtIndices:selectedRowIndices];

// -------------------------------------------------------
// SELECT ROW BELOW OR EQUAL TO THE LAST DELETED ROW.
// -------------------------------------------------------

// Retrieve the highest selection index (lowest row).
NSInteger highestSelectedRowIndex = NSNotFound;
for (NSUInteger index = selectedRowIndices.firstIndex; index < selectedRowIndices.count; ++index) {
    if (index > highestSelectedRowIndex) {
        highestSelectedRowIndex = index;
    }
}
if (highestSelectedRowIndex != NSNotFound && highestSelectedRowIndex < [m_tableView numberOfRows]) {
    // 1) Get the selected object for the highest selected index.
    // TODO: Retrieve the object from m_tableView or m_arrayController somehow!?!
    // 2) Update the table view selection.
    //[self updateTableViewWithSelectedObjects:...];
}

However, I can not find out how I can identify the object that match with the highest index of the former selection.
Why? I would like to move the new selection to the row below the last selection.


ATTENTION: The above code contains several errors!

This is what I ended up with - thanks to Thomas for clarifications.

NSUInteger nextSelectedRowIndex = selectedRowIndices.firstIndex;
if (nextSelectedRowIndex != NSNotFound) {
    if (nextSelectedRowIndex >= m_tableView.numberOfRows) {
        nextSelectedRowIndex = m_tableView.numberOfRows - 1;
    }
    id nextSelection = [[m_arrayController arrangedObjects] objectAtIndex:nextSelectedRowIndex];
    [self updateTableViewWithSelectedObjects:nextSelection]];
}

Solution

  • The indexes in an NSIndexSet are in order. There's no need for a loop to find the highest.

    If you want to select a given row, just invoke -selectRowIndexes:byExtendingSelection: with the new selection you want to establish. For example, [m_tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:highestSelectedRowIndex] byExtendingSelection:NO]. You don't need to know which object that is.

    If you still want to know the object, you have to get the array controller's arrangedObjects and apply -objectAtIndex: to that.