• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Live Sorting a NSTreeController
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Live Sorting a NSTreeController


  • Subject: Live Sorting a NSTreeController
  • From: Arved von Brasch <email@hidden>
  • Date: Sat, 27 May 2006 18:38:01 +1000

Greetings Cocoa Dev List,

Yet another NSTreeController query. Are there any examples out there for Live Sorting of an NSTreeController?

This problem for me, stems from supporting drag and drop ordering of items in an NSOutlineView. There are several examples of implementing CoreData ordering in an NSOutlineView backed by bindings through an NSTreeController. I have this working fine, and am happy with it. My problem stems from the being able to undo these actions. When ordering by drag and drop, a value is changed in the ManagedObject, and hence the undo manager will be notified and it will be possible to undo this action. The trouble is that undoing the action will not cause the OutlineView (or NSTableView, if an NSArrayController is being used) to be notified, and thus, there will be no visual feedback to the user that the undo has actually taken place, until the TableView or OutlineView is resorted.

I see two ways of getting around this problem:

1. Disable undos for drag and drops. Easy to do, but seems a bit of a cop-out.

2. Establish a means of notification when an undo occurs. This seems easiest to manage with live sorting.

I'm defining live sorting to be forcing the backing of the TableView or OutlineView to resort immediately when a change is made.

This is really easy to do with a NSArrayController and NSTableView. In the NSArrayController subclass, simply add:

- (void)awakeFromNib {
	[super awakeFromNib];

	// Any other set up code.

[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(resortTable:) name: NSControlTextDidEndEditingNotification object: theTable];
[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(resortTable:) name: NSUndoManagerDidUndoChangeNotification object: [[self managedObjectContext] undoManager]];
[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(resortTable:) name: NSUndoManagerDidRedoChangeNotification object: [[self managedObjectContext] undoManager]];
}


- (void)resortTable: (NSNotification *)notification {
	[self rearrangeObjects];
}

You may also need to put a manual rearrange in addObject:, if you want newly inserted objects to be sorted as well. This should now behave as expected for undos of drag and drop sorting; namely, the table will resort after a drag and drop has been undone. For efficiency, you may want to put in some checks to see what kind of undo operation was performed, if reloading your table is expensive.

For NSTreeController / NSOutlineView one would expect the situation to be just as straight forward, but of course it isn't. The first trouble comes in trying to decide where to add the initial value for the positioning attribute. The ideal behaviour is for the order that objects are added to the OutlineView to be remembered. Hence, setting a default value in the model is not the best solution. It can't be set in a redefinition of newObject because newObject is not called through addChild:, and the documentation claims it shouldn't be called at all. It can't be set in awakeFromInsert of the ManagedObject, because at that point you don't know if the object is destined to be a child or a parent. It can't be done simply in add: or addChild: because I haven't been able to find a reliable method of returning the newly created item. This is also a problem if you want to automatically set the editable column of the new row through editColumn:row:withEvent:select: You can redefine add: and addChild: completely to create the object and insert it into the TreeController, which will then let you use editColumn. Doing this, however, makes it difficult to do the resort trick, because of the way rearrange seems to be implemented. insertObject:atArrangedObjectIndexPath: does not seem to always fetch the newly created object, and calling rearrange will cause add: and addChild: to occasionally fail.

So it seems that you can have editColumn:row:withEvent:select: or live sorting but not both. At least, not with NSTreeController.

Another possible solution could be to simulate a double click on a table header, to resort the table that way. I can't work out an easy way to actually do this, however.

Does anyone have an ideas on how to support all these issues simultaneously?

1. Undos cause outline view to resort if the undo affects the attribute for the current sort descriptor.

2.  Live resorting when objects are added and edited.

3. When new entities are added, editing is started immediately in a specific table column.

Cheers,

Arved
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


  • Prev by Date: [Q] omissible method declaration in interface file
  • Next by Date: Re: [Q] omissible method declaration in interface file
  • Previous by thread: RE: [Q] omissible method declaration in interface file
  • Next by thread: AddressBook Country Code -> Address Format
  • Index(es):
    • Date
    • Thread