tableview delegate sortDescriptorsDidChange not getting called

Discussion in 'Mac Programming' started by BenCoffman, Sep 5, 2009.

  1. BenCoffman macrumors newbie

    Joined:
    Sep 5, 2009
    #1
    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];
    } 
    
    
     
  2. mdeh macrumors 6502

    Joined:
    Jan 3, 2009
    #2

    Try your code with the declaration and definition **exactly** the same.
     
  3. BenCoffman thread starter macrumors newbie

    Joined:
    Sep 5, 2009
    #3

    I changed it to this

    Code:
    - (void)tableView:(NSTableView *)aTableView 
    sortDescriptorsDidChange:(NSArray *)oldDescriptors 
    
    Cleaned targets and rebuilt. No love.
     
  4. warwick macrumors newbie

    Joined:
    Sep 6, 2009
    #4
    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.
     
  5. BenCoffman thread starter macrumors newbie

    Joined:
    Sep 5, 2009
    #5

    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];
    
     
  6. warwick macrumors newbie

    Joined:
    Sep 6, 2009
    #6
    The tableView:sortDescriptorsDidChange: method won't be called unless some other piece of code calls setSortDescriptors: on your tableview.
     
  7. BenCoffman thread starter macrumors newbie

    Joined:
    Sep 5, 2009
    #7
    I'm not entirely sure that is correct. Here is what the apple Docs say about this function

    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. :)
     
  8. yoavcs macrumors regular

    Joined:
    Apr 7, 2004
    Location:
    Israel
    #8
    You can also invoke that method by clicking on column headers in the UI to cause a sort to happen.
     
  9. warwick macrumors newbie

    Joined:
    Sep 6, 2009
    #9
    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?
     
  10. BenCoffman thread starter macrumors newbie

    Joined:
    Sep 5, 2009
    #10
    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?
     
  11. kainjow Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #11
    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.
     

Share This Page