views:

127

answers:

2

Hello experts,

I have troubles getting my NSTableView keep the contents of a to-many relationship ordered.

What I have is an entity "Relationship" in a to-many relationship with an entity "Card" both managed by an NSArrayController. Card has 2 attributes, "number" (int) and "name" (String) displayed via Bindings in two columns of a NSTableView. I can sort table columns permanently, but on every new insert of a card, the rows of the table view rearrange themselves randomly (however, deletion of a card keeps row order).

What I want is the following behaviour: The user can sort columns, but when he inserts a card, the card should be displayed as the very last row of the table (not sorted directly upon insert, but of course, not showing random rearranging, either). Only when the user sorts again, the new card will be sorted, too.

I know that the contents of a to-many relationships are kept as sets, but I do not know how to go on from there.

I appreciate any help.

A: 

Essentially, you need to cache the relation set in a sorted NSArray.

Create an NSArray that is a version of the relation NSSet with [fooSet allObjects]. NSArray has several sorting methods you can use to sort the contents. When a user adds a new card, add it to the end of the array and add it to the parent object relationship.

John Franklin
Thank you very much for your answer! As I am a beginner in Core Data, I am not sure where the part of logic you mentioned belongs. Could you be a bit more specific about where to cache the relation set and how to add it again to the parent object relationship?
Core
+1  A: 

If the table's columns are bound to a NSArrayController then the order of the rows should never be random because arrays have a fixed order. Moreover, the fetch used by the array controller should have a sort descriptor on it that will enforce a sort order.

The randomization indicates that somewhere you're mapping a set onto the array. (Sets contain unique objects in a random order.)

As an aside, putting a newly added row out of sort order at the end of the table is difficult to implement and is bad UI design.

It's difficult to implement because Core Data and bindings are intended to easily and accurately display the data in is logical relationships not an arbitrarily visual location in the UI. If the end of the table has no logical meaning to added Card object then you will have to do a lot of work to make it show up there.

It's bad UI because the user won't understand why a newly added card shows up at the end of the table when all the other cards appear in some logical order. If you have a table sorted alphabetically on name, the user won't understand why a card whose name is "Foxtrot" appears at the end of the table after "Zulu".

Instead, you should either display the new card in an UI element external to the table and/or scroll the table to the properly sorted location of the new card.

TechZen
Thanks for your answer. As I am using Core Data, I bound the NSArrayController for the Card entity to the ContentSet of the NSArrayController of the Category entity, making a to-many relationship. Binding to the ContentArray is not possible! Thus, (I guess) what the NSTableView presents is a Set. By clicking onto the table header (the columns are bound to the Card's attributes) the table gets sorted properly. However, upon inserting a new card, the rows start jumping.(This is independent of whether I want the card to add at the end of the table)
Core