NSArrayController Managing / Sorting NSManagedObjects

  • Hi,

    I have an NSTableView that displays a set of Activity objects, which
    are subclasses of NSManagedObject, all of which are managed by a
    custom NSArrayController.  Each Activity has a sortIndex property,
    which is used to... wait for it... sort the activities.

    The array controller adds logic to update the sortIndex as objects are
    added, removed or re-ordered.  It's this last part that's giving me
    grief.  The table supports drag-and-drop.  The idea is that when an
    Activity is dragged up or down in the list, the sortIndex for all of
    the activities get updated, so that the next time the list of
    activities is displayed, the activities maintain the order in which
    they were placed by the user.

    The array controller's sort descriptors binding is bound to an array
    with a single NSSortDescriptor, set to order the objects by
    sortIndex.  I think this is causing some grief.  Also, the code that
    assigns new sortIndexes for each object calls [arrayController
    arrangedObjects] to get the array controller's objects.  From my
    reading of the documentation, this calls arrangeObjects on the
    underlying array, which I don't really want to do until all of the
    Activity objects' sortIndexes have been updated to reflect their new
    positions in the array.

    The objects that are dropped are assigned new sortIndexes based on
    their new indexes immediately after being dropped into the array.  I'm
    not doing anything with the sortIndexes for the items in the array
    that haven't been moced until later.  In the interim, I believe that
    calling [arrayController arrangedObjects] is trying to make the
    NSArrayController arrange its objects based on its sort descriptor
    (sortIndex), while one or more of the objects in the set share the
    same sortIndex.  This is causing problems.

    I'm hoping someone can point me to some sample code that addresses
    this issue.  I've looked at Demo Monkey and a couple of other samples
    I found on the web without being enlightened.  Jonathan Dann has
    sample code using sortIndex and an NSTreeController, but updating the
    treeController doesn't involve rearranging its items first, so, it
    doesn't quite work.

    Possible solutions I can see:

    1.  manually assigning new sortIndexes to all objects from the point
    of insertion through the end of the array / set immediately upon
    insertion of the moved objects, or:
    2.  copying the entire array after insertion and then using the copied
    array to assign new indexes:

    for (Activity *anActivity in activitiesArrayCopy) {
    [anActivity setValue:[NSNumber numberWithInt:[activitiesArrayCopy
    indexOfObject:anActiviity]] forKey:@"sortIndex"]
    }

    But, I think there's a cleaner, more elegant solution out there that
    I'm not seeing.

    Any suggestions would be appreciated.

    Thanks.

    Brad
  • I found some sample code that addresses this:

    http://shanecrawford.org/2008/37/sorting-a-coredata-backed-nsarraycontrolle
    r/


    On Aug 7, 2009, at 2:50 PM, Brad Gibbs wrote:

    > Hi,
    >
    > I have an NSTableView that displays a set of Activity objects, which
    > are subclasses of NSManagedObject, all of which are managed by a
    > custom NSArrayController.  Each Activity has a sortIndex property,
    > which is used to... wait for it... sort the activities.
    >
    > The array controller adds logic to update the sortIndex as objects
    > are added, removed or re-ordered.  It's this last part that's giving
    > me grief.  The table supports drag-and-drop.  The idea is that when
    > an Activity is dragged up or down in the list, the sortIndex for all
    > of the activities get updated, so that the next time the list of
    > activities is displayed, the activities maintain the order in which
    > they were placed by the user.
    >
    > The array controller's sort descriptors binding is bound to an array
    > with a single NSSortDescriptor, set to order the objects by
    > sortIndex.  I think this is causing some grief.  Also, the code that
    > assigns new sortIndexes for each object calls [arrayController
    > arrangedObjects] to get the array controller's objects.  From my
    > reading of the documentation, this calls arrangeObjects on the
    > underlying array, which I don't really want to do until all of the
    > Activity objects' sortIndexes have been updated to reflect their new
    > positions in the array.
    >
    > The objects that are dropped are assigned new sortIndexes based on
    > their new indexes immediately after being dropped into the array.
    > I'm not doing anything with the sortIndexes for the items in the
    > array that haven't been moced until later.  In the interim, I
    > believe that calling [arrayController arrangedObjects] is trying to
    > make the NSArrayController arrange its objects based on its sort
    > descriptor (sortIndex), while one or more of the objects in the set
    > share the same sortIndex.  This is causing problems.
    >
    > I'm hoping someone can point me to some sample code that addresses
    > this issue.  I've looked at Demo Monkey and a couple of other
    > samples I found on the web without being enlightened.  Jonathan Dann
    > has sample code using sortIndex and an NSTreeController, but
    > updating the treeController doesn't involve rearranging its items
    > first, so, it doesn't quite work.
    >
    > Possible solutions I can see:
    >
    > 1.  manually assigning new sortIndexes to all objects from the point
    > of insertion through the end of the array / set immediately upon
    > insertion of the moved objects, or:
    > 2.  copying the entire array after insertion and then using the
    > copied array to assign new indexes:
    >
    > for (Activity *anActivity in activitiesArrayCopy) {
    > [anActivity setValue:[NSNumber numberWithInt:[activitiesArrayCopy
    > indexOfObject:anActiviity]] forKey:@"sortIndex"]
    > }
    >
    > But, I think there's a cleaner, more elegant solution out there that
    > I'm not seeing.
    >
    > Any suggestions would be appreciated.
    >
    >
    > Thanks.
    >
    > Brad
previous month august 2009 next month
MTWTFSS
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31            
Go to today