简体   繁体   中英

Sorting NSTableColumn with NSArrayController

I have a NSArrayController bound to an NSTableView so the table column like the following:

NSTableView bindings:
Content -> ArrayController.arrangedObjects
SelectionIndexs -> ArrayController.arrangedObjects
SortDescriptors -> ArrayController.sortDescriptors

NSTableColumn bindings:
Value -> ArrayController.arrangedObjects.description

When I try and sort it using the column header it just crashes with something like

error setting value for key path sortDescriptors of object NSArrayController

Any ideas?

I struggled with the exact same problem today.

It seems that binding the content and selectionIndexes of the tableView to the array controller IB > inspector window > select your tableView > bindings tab , disables the sorting by clicking on the table header. This makes sense, because the table view now shows you the exact contents (and ordering) of the array controller.

I unchecked these bindings in the IB, also removed any sort keys from the table columns IB > inspector window > select your NSTableColumn > attributes pane . Select the checkbox Creates Sort Descriptor in the table column's binding tab. No sortDescriptor is needed on the table, although I think binding the table's sortDescriptor to Shared User Defaults Controller saves the ordering when you quit your application.

If you need to sort your table, put a sortDescriptor on the array controller, maybe in the awakeFromNib .

- (void)awakeFromNib {
    [super awakeFromNib];
    [self setSortDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"propertyOfYourObject" ascending:YES selector:@selector(compare:)]]];
}

This does not interfere with clicking the table column headers.

I couldn't get a sortDescriptor on the array controller to work with bindings.

I see several issues in your binding attempt.

  1. One doesn't usually need to bind the NSTableView at all. Binding the values of specific NSTableColumn s to the NSArrayController is enough.

  2. You try to bind something against a .description property. Please remember - " description " is like a "reserved word" in Obj-C. Any NSObject should present itself as NSString in its "description" method. This is what is called when you po <object> in the debugger, or pass an NSObject to NSLog via "%@". So... probably you'd want to rename your property to something else.

  3. You do NOT need to bind the sort descriptors of the NSArrayController or the NSTableView or the NSTableColumn at all. As it happens, when you bind an NSTableColumn 's value to the NSArrayController 's arrangedObjects , the NSTableColumn (actually the NSColumnHeader ) object knows to set the NSArrayController 's sortDescriptor to the same path as the one you specified for the column's value binding - as you click on the column header. In other words - sorting by clicking on column headers comes free, if you just bind your column's value to the NSArrayController's arrangedObjects.

Documentation on table binding is bad and frustrating. There are several different schemes for working with a Table, and debugging binding problems is a real nightmare. However, there are plenty essays and tutorials on the net for this.

Hope this helps.

Let me suggest you a simple way to do this -

NSTableColumn bindings:

Value -> 

Bind to: ArrayController

Controller Key : arrangedObjects

Model Key Path : keyPath (such as name)

If you are new to using bindings with table view, this article will be of great help to you-

EDIT: Project relocated to Github. (No more explanation - code only)

NSTableView, NSArrayController and More Bindings

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM