NSTableView - select by clicking a row after editing is completed, clicking another row

I have an NSTableView that populates without bindings.

In the datasource method tableView tableView:objectValueForTableColumn:row: I re-sort my data and tell how the table view reloads after editing the model so that the correct sort order is restored after editing.

If the user finishes editing by clicking on another line, however, and the sort order has changed due to the editing just finished, it may happen that the line that the user intended to select has just moved after clicking it, so another line is selected instead the string that is now in this place.

I tried various combinations of NSTableViewDelegate methods, but could not find a solution that adjusts the selection so that when re-sorting after editing is complete, the selected row will be selected. How can I achieve this?

+4
source share
2 answers

I would use this:

I recommend sort your data in an NSTableView delegate setObjectValue: instead of objectValueForTableColumn:

And change the selection in the NSTableView delegate selectionIndexesForProposedSelection:

This decision drives one choice. If you want him to manage single and multiple choices, I would change my answer. If the user double-clicks, it does not work, since it changes the selection to a second click.

You need the following variables:

 int originalRowIndex; NSUInteger newRowIndex; 

I initialize this variable: originalRowIndex = -1;

 - (void)tableView:(NSTableView *)aTable setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)aColumn row:(int)rowIndex { id objectAtRow = [myMutableArray objectAtIndex:rowIndex]; NSString *columnKey = [aColumn identifier]; [objectAtRow setValue:anObject forKey:columnKey]; originalRowIndex = rowIndex; // get the original index [myMutableArray sortUsingDescriptors:[aTable sortDescriptors]]; // re-sort the mutable array newRowIndex = [myMutableArray indexOfObjectIdenticalTo:objectAtRow]; // get the new index if (newRowIndex == originalRowIndex) originalRowIndex = -1; // same position } // not called on empty selection - (NSIndexSet *)tableView:(NSTableView *)tableView selectionIndexesForProposedSelection:(NSIndexSet *)proposedSelectionIndexes { int oIndex = originalRowIndex; originalRowIndex = -1; if (oIndex > -1 && [proposedSelectionIndexes count] > 1) { // if oIndex = -1 or multi selection , do nothing int i = [proposedSelectionIndexes firstIndex]; if (oIndex < newRowIndex) { if (i > oIndex && i <= newRowIndex) return [NSIndexSet indexSetWithIndex:(i - 1)];//shift the row index } else { if (i < oIndex && i >= newRowIndex) return [NSIndexSet indexSetWithIndex:(i + 1)];//shift the row index } //else doesn't change the selection, this index is out of range (originalIndex...newIndex) } return proposedSelectionIndexes;// doesn't change the selection } 
+3
source

I always did it with difficulty: before I do something needed for recovery, I remember the current selection, not the row index, but something that I can find in my data. Often I have a set of dictionaries, so I just remember the dictionary pointer.

Performing all that I need to do in the table view, I just scan the data again, looking for my object to find the new index ...

+2
source

All Articles