Hi Scott,

Yes I'm implementing the delegate method. Sorting is working just fine: when I 
click the column headers sort descriptors are updated, the delegate is 
informed, the controller does its thing with the data and all is well.

The issue is when I try to accomplish this programatically (from a menu, in 
fact).

If I call [NSTableView setHighlightedColumn:], the sort descriptors are not 
changed and the delegate is not informed (even though the UI now appears to 
indicate a different sorted column).

If I call [NSTableView setSortDescriptors:] the column highlight is not changed 
though the delegate IS informed (and again, the table view order does not match 
the highlighted column - in fact the sorting indicator does update for the 
right column but the blue highlight is elsewhere).

Because of this programmatic disconnect between these two methods (which may 
well be intentional though I don't quite see the logic of it, and maybe that's 
where the documentation could be clarified), I have to duplicate the work that 
NSTableView does to change its internal sort descriptors. At the very least 
there ought to be an entry point to do that.

So far I'm getting the delegate method to search for the column having a sort 
descriptor with a matching key and calling -setHighlightColumn: with that 
column. That takes care of highlighting the column to match the sort 
descriptor. The other part is the code which reorders the array of sort 
descriptors to match what I want. I've got that part working now by searching 
on the descriptor's key rather than assuming that the prototype gets copied to 
the array as is, i.e:

        NSTableColumn* column = [mItemsListView 
tableColumnWithIdentifier:columnIdentifier];
        if( column && !(column == [mItemsListView highlightedTableColumn]))
        {
                NSSortDescriptor* sd = [column sortDescriptorPrototype];
                
                if( reverse )
                        sd = [sd reversedSortDescriptor];
                
                // just switching the column isn't enough - the sort 
descriptors must be updated ourselves
                // (grr, why doesn't the table view do this?)
                
                NSMutableArray* sortDescs = [[mItemsListView sortDescriptors] 
mutableCopy];

                // remove all sort descriptors having the same key
                
                NSEnumerator* iter = [[mItemsListView sortDescriptors] 
objectEnumerator];
                NSSortDescriptor* desc;
                
                while(( desc = [iter nextObject]))
                {
                        if([[desc key] isEqualToString:[sd key]])
                                [sortDescs removeObject:desc];
                }
                
                [sortDescs insertObject:sd atIndex:0];
                
                // setSortDescriptors informs the delegate (self) which updates 
the highlighted column
                
                [mItemsListView setSortDescriptors:sortDescs];
                [sortDescs release];
        }

and my delegate method:

- (void)                tableView:(NSTableView*) aTableView 
sortDescriptorsDidChange:(NSArray*) oldDescriptors
{
        // pass this on to the next level controller which performs the actual 
sort and reload

        if([[self delegate] 
respondsToSelector:@selector(sortDescriptorsChanged:)])
                [[self delegate] sortDescriptorsChanged:oldDescriptors];
        
        // keep the highlighted column in synch (workaround for odd behaviour 
with programmatic sorting)
        
        NSSortDescriptor* sd = [[aTableView sortDescriptors] objectAtIndex:0];
        
        if( sd )
        {
                NSEnumerator* iter = [[aTableView tableColumns] 
objectEnumerator];
                NSTableColumn*  column;
                
                while(( column = [iter nextObject]))
                {
                        if([[[column sortDescriptorPrototype] key] 
isEqualToString:[sd key]])
                        {
                                [aTableView setHighlightedTableColumn:column];
                                break;
                        }
                }
        }
}


On 06/07/2010, at 1:15 PM, Scott Anguish wrote:

> are you implementing the delegate method?
> 
> 
> - (void)tableView:(NSTableView *)tableView sortDescriptorsDidChange:(NSArray 
> *)oldDescriptors
> {
>       // the sort descriptors are specified in Interface Builder for the 
> lastName column and the relationship column
>       // the both specify the respective keys, and use the compare: method to 
> do the sorting
>       // this message is sent to the delegate when the data is sorted by 
> clicking on one of those column headers
>       [peopleArray sortUsingDescriptors: [tableView sortDescriptors]];
>    [tableView reloadData];
> }
> 
> 
> I’m setting the sort information in Interface Builder on each column, 
> specifying the key to sort on, and the compare selector (which is compare: 
> which probably isn’t the best for localized content). I agree that both the 
> hidden and non-hidden columns should have the same key and compare selector 
> for both columns.
> 
> When you click on one of those table column headers, the delegate is notified.
> 
> Now, this does ‘destroy’ the natural sort order. But you can easily copy that 
> natural order array into a ‘displayed’ array when loaded, and then upon some 
> action, put a copy of that natural array in the displayed array. The delegate 
> implementation above would do something like 
> 
> self.displayArray=[naturalOrderArray sortedArrayUsingDescriptors:[tableview 
> sortDescriptors]];
> 
> Is this helpful? If you’re having sorted issues that need documenting file a 
> bug and send me the number ASAP. Seriously, ASAP.

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to