Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

BenCoffman

macrumors newbie
Original poster
Sep 5, 2009
9
0
I'm trying to sort my tableColumn, but the sortDescriptorsDidChange is not getting called

Three other delegate functions are getting called.

Code:
- (void)tableView:(NSTableView *)aTableView
		setObjectValue:(id)anObject
		forTableColumn:(NSTableColumn *)aTableColumn
				   row:(int)rowIndex

- (id)tableView:(NSTableView * )aTableView
		objectValueForTableColumn:(NSTableColumn *)aTableColumn
		                      row:(int)rowIndex

- (int)numberOfRowsInTableView:(NSTableView *)aTableView


All above three get called but the one below does not. I have no idea why.

Code:
- (void)tableView:(NSTableView *)tableView sortDescriptorsDidChange:(NSArray *)oldDescriptors

I've set up a breakpoint and it's not even stopping inside the function.

Further here is my exact code.

Code:
- (int)numberOfRowsInTableView:(NSTableView *)aTableView
{
	return [employees count];
}

- (id)tableView:(NSTableView * )aTableView
		objectValueForTableColumn:(NSTableColumn *)aTableColumn
		                      row:(int)rowIndex
{
	//What is the identifier for the column?
	NSString *identifier = [aTableColumn identifier];
	
	//What person?
	Person *person = [employees objectAtIndex:rowIndex];
	
	//What is the value of the attribute named identifier
	return [person valueForKey:identifier];
}

- (void)tableView:(NSTableView *)aTableView
		setObjectValue:(id)anObject
		forTableColumn:(NSTableColumn *)aTableColumn
				   row:(int)rowIndex
{
	NSString *identifier = [aTableColumn identifier];
	Person *person = [employees objectAtIndex:rowIndex];
	
	//Set the value for the attribute named identifier
	[person setValue:anObject forKey:identifier];
}

- (void)tableView:(NSTableView *)atableView 
sortDescriptorsDidChange:(NSArray *)oldDescriptors 
{
	NSArray *newDescriptors = [atableView sortDescriptors];
	[employees sortUsingDescriptors:newDescriptors];
	[tableview reloadData];
}
 
I'm trying to sort my tableColumn, but the sortDescriptorsDidChange is not getting called

All above three get called but the one below does not. I have no idea why.


- (void)tableView: (NSTableView *)tableView sortDescriptorsDidChange: (NSArray *)oldDescriptors

- (void)tableView: (NSTableView *)atableView
sortDescriptorsDidChange: (NSArray *)oldDescriptors


Try your code with the declaration and definition **exactly** the same.
 
Try your code with the declaration and definition **exactly** the same.


I changed it to this

Code:
- (void)tableView:(NSTableView *)aTableView 
sortDescriptorsDidChange:(NSArray *)oldDescriptors

Cleaned targets and rebuilt. No love.
 
tableView:sortDescriptorsDidChange: is a 10.6 only method. Are you certain you're building against the 10.6 libraries?

Also, when are you expecting this to be called? I don't see you setting the sortDescriptor at any point.
 
tableView:sortDescriptorsDidChange: is a 10.6 only method. Are you certain you're building against the 10.6 libraries?

Also, when are you expecting this to be called? I don't see you setting the sortDescriptor at any point.


Upgrading to 10.6 was a good suggestion, though it did not solve my problem. It however made the very annoying
unable to read unknown load command 0x80000022
error go away.

Unfortunately xcode still does not break in the method during debug and sorting is not working.

I think I set the sortDescriptor in the the method above here it is again for convenience.
Code:
	NSArray *newDescriptors = [aTableView sortDescriptors];
	[employees sortUsingDescriptors:newDescriptors];
 
The tableView:sortDescriptorsDidChange: method won't be called unless some other piece of code calls setSortDescriptors: on your tableview.
 
The tableView:sortDescriptorsDidChange: method won't be called unless some other piece of code calls setSortDescriptors: on your tableview.

I'm not entirely sure that is correct. Here is what the apple Docs say about this function

Invoked by aTableView to indicate that sorting may need to be done.

- (void)tableView:(NSTableView *)aTableView sortDescriptorsDidChange:(NSArray *)oldDescriptors

Parameters
aTableView
The table view that sent the message.

oldDescriptors
An array that contains the previous descriptors.

Discussion
The data source typically sorts and reloads the data, and adjusts the selections accordingly. If you need to know the current sort descriptors and the data source does not manage them itself, you can get the current sort descriptors by sending aTableView a sortDescriptors message.

Implementation of this method is optional.

http://developer.apple.com/mac/libr...ataSource/tableView:sortDescriptorsDidChange:

It does not state that setSortDescriptors needs to be called. I could be wrong though. I won't stand behind my answer. :)
 
You can also invoke that method by clicking on column headers in the UI to cause a sort to happen.
 
In Cocoa, there are often datasource or delegate methods that contain phrases like "didChange" or "willChange". These methods are called only when the value they're referring to actually changes.

The method we're looking at here, tableView:sortDescriptorsDidChange: is a method of this type. The name of the method implies that it will be called after the sort descriptor for a given tableview changes. To the best of my knowledge, there are two times when this can happen.

The first way is when you've used bindings to populate a tableview, then a column header is clicked. That's not what you're doing here.

The second way is when setSortDescriptors: is called explicitly. By default, a table has no sortDescriptor. In the code you've provided, a sortDescriptor is never set. Therefore, the sortDescriptor never changes and tableview:sortDescriptorsDidChange: will never be called.

At what point in your programs execution do you believe this method should be called?
 
In Cocoa, there are often datasource or delegate methods that contain phrases like "didChange" or "willChange". These methods are called only when the value they're referring to actually changes.

The method we're looking at here, tableView:sortDescriptorsDidChange: is a method of this type. The name of the method implies that it will be called after the sort descriptor for a given tableview changes. To the best of my knowledge, there are two times when this can happen.

The first way is when you've used bindings to populate a tableview, then a column header is clicked. That's not what you're doing here.

The second way is when setSortDescriptors: is called explicitly. By default, a table has no sortDescriptor. In the code you've provided, a sortDescriptor is never set. Therefore, the sortDescriptor never changes and tableview:sortDescriptorsDidChange: will never be called.

At what point in your programs execution do you believe this method should be called?

Warwick -- another good post -- I'll stop saying this because it's getting redundant.

I would like it to be called when I hit the table's column header.

I think you are telling me i have not set any criteria for my table column to be sorted, but with setSortDescriptors I can set criteria which in turn will cause my sortDescriptor tableview to get called

I can't seem to find any good example on how to use setSortDescriptors? Links or suggestions?
 
tableView:sortDescriptorsDidChange: is a 10.6 only method. Are you certain you're building against the 10.6 libraries?

The docs are semi-misleading. The @protocol methods are 10.6+ but they still work on 10.3 and up if you target that SDK. I'm guessing the reason they say 10.6+ is because if you link to the 10.6 SDK they'll use conformsToProtocol, but for 10.3+ it might use respondsToSelector:


Regarding getting this method to work, the way I've always done it is to setup the sort descriptors for each column in IB. Then that method gets called magically and you just resort your array, although I believe an array controller will handle it all if you're using that.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.