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 }
source share