Sorting NSTableView
Asked Answered
R

4

10

I have two coloumn in NSTableView as Name and Salary with 5-10 values. I want to sort these coloumn after click on header of both the column. There is lots of data present in Internet but I am not able to use these. Please help me to do this in cocoa.

Thanks in advance and appreciate any help.

Reptant answered 19/6, 2012 at 6:47 Comment(1)
I have two column in table, as Name and Salary, I put values hardcoded without binding, Now I want to sort data, how I perform this task.Reptant
B
19

Each table column has a method setSortDescriptorPrototype Sort descriptors are ways of telling the array how to sort itself (ascending, descending, ignoring case etc.) Iterate over each of the columns you want as sortable and call this method on each of those columns, and pass the required sort descriptor (In my case I'll be using the column identifier)

for (NSTableColumn *tableColumn in tableView.tableColumns ) {

    NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:tableColumn.identifier ascending:YES selector:@selector(compare:)];
    [tableColumn setSortDescriptorPrototype:sortDescriptor];
}

After writing this piece of initialization code, NSTableViewDataSource has a method - (void)tableView:(NSTableView *)aTableView sortDescriptorsDidChange:(NSArray *)oldDescriptors that notifies you whenever a sort descriptor is changed, implement this method in the data source and send a message to the data array to sort itself

- (void)tableView:(NSTableView *)aTableView sortDescriptorsDidChange:(NSArray *)oldDescriptors
{
    self.data = [self.data sortedArrayUsingDescriptors:sortDescriptors];
    [aTableView reloadData];
}

This method will get fired each time a column header is clicked, and NSTableColumn shows a nice little triangle showing the sorting order.

Blear answered 29/6, 2012 at 8:35 Comment(0)
C
7

I stumbled upon this question while looking for the easiest way of implementing something similar. Although the original question is old, I hope someone finds my answer useful! Please note that I am using Xcode 5.1.1

Ok so to do this you need to:

  1. select the actual column you want to sort in your table.
  2. In your Attributes Inspector you need to fill in two fields: Sort Key, and Selector.
  3. In the Sort Key field, you need to enter the value of your Identifier. The value of your Identifier is located in your Identity Inspector.
  4. In the Selector field you need to enter a suitable selector method based on the object type in the column. The default method is; compare:

Based on the Table View Programming Guide for Mac. The compare: method works with NSString, NSDate, and NSNumber objects. If your table column contains only strings, you may want to consider using the caseInsensitiveCompare: method if case sensitivity is unimportant. However, consider replacing these method signatures with the localizedCompare: or localizedCaseInsensitiveCompare: methods to take into the account the user’s language requirements.

Finally, you need to declare the tableView:sortDescriptorsDidChange: method in your Table View Controller in the format shown below:

-(void)tableView:(NSTableView *)mtableView sortDescriptorsDidChange:(NSArray *)oldDescriptors
{
    [listArray sortUsingDescriptors: [mtableView sortDescriptors]];
    [tableView reloadData];
}
Climate answered 5/6, 2014 at 12:41 Comment(2)
The sort key field should be a property in the data object, not the identifier of the column. (although they might the same)Bourbonism
can we keep identifier of column and data object property samePaleogeography
C
0

Just had lately the same issue to get tableView sorted. My approach :

  • bind your sortDescriptors to tableview's arrayController
  • bind tableview's sortDescriptors to Arraycontroller's sort descriptor
  • perform the settings in attribute inspector (see Tosin's answer above)

Worked perfect for me. No need to set prototypes for columns or something else.

Carnes answered 28/8, 2020 at 8:46 Comment(0)
D
0

Thanks very much ,It is usefullly for my question. my code like this

First, set unique values in the XIB interface,like name...

- (void)viewDidLoad {
    [super viewDidLoad];
        self.itemTableView.dataSource = self;
        self.itemTableView.delegate = self;
        self.itemTableView.selectionHighlightStyle = NSTableViewSelectionHighlightStyleRegular;
        self.itemTableView.usesAlternatingRowBackgroundColors = YES;

        for (NSTableColumn *tableColumn in self.itemTableView.tableColumns ) {
            NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:tableColumn.identifier ascending:NO selector:@selector(compare:)];
        [tableColumn setSortDescriptorPrototype:sortDescriptor];
        }
}

-(void)tableView:(NSTableView *)tableView sortDescriptorsDidChange:(NSArray<NSSortDescriptor *> *)oldDescriptors{
    NSLog(@"sortDescriptorsDidChange:%@",oldDescriptors);

    [self.itemArr sortUsingDescriptors:[tableView sortDescriptors]];

    [self.itemTableView reloadData];
}
Damron answered 16/1, 2021 at 14:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.