NSOutlineView woes
NSOutlineView woes
- Subject: NSOutlineView woes
- From: Graham Cox <email@hidden>
- Date: Mon, 21 Mar 2016 14:20:50 +1100
I’m really struggling with NSOutlineView. I’ve used this class a lot in the past and never run into these sorts of issues, but this time around it’s proving difficult. One reason is that I’m trying to do the right thing and have the table animate when the user does stuff that changes the model it’s displaying.
The outline view (view based) represents a structure which is not that complicated.
Let’s say this is my table, where a + symbol indicates a child object of the parent it belongs to (aside: oh for the ability to attach images to these mails!)
parent
+child 1
+child 2
+parent 2
++child 1
+child 3
+child 4
The very top level parent is optional - my code can hide or show this at the user’s discretion. That adds a little bit of complication, because when it’s hidden, the root object is passed as nil by NSOutlineView, but my code knows about that and takes care of it. It does mean that the row indexes need to allow for that or not as the case may be.
The user might drag ++child1 out of +parent 2 and deposit it between +child 3 and +child 4. This is a typical test case I’m having issues with. When I accept the drop, my model is modified by removing the child from +parent 2 and inserting it into parent at the computed index. So my model performs a remove step, followed by an insert step. At each of these steps, notifications are received by the controller of the outline view and used to cause table row animations which reflect the changes. These also work when Undo operates on my data model, and also for the separate delete and insert cases, since the same code is invoked in the model, the same notifications are sent, and the table should blindly follow. It’s important to realise then that the table receives a delete followed by an insert - there is no easy way to use the (move) method on a table that animates one row to another location. That shouldn’t matter however.
My model gets as far as the delete step, and the table responds to the notification by calling -[NSOutlineView removeItemsAtIndexes:inParent:withAnimation:].
This method takes an index set which contains the index of the item RELATIVE to the parent. In this case, that value would be 0 for ++child 1, as this is the 0th item contained by +parent2. The table overall however, is really a flat list, so when I call -rowForItem: with +child 1 as an argument, I should get back 4 (or 3 if the root item is not displayed). Sometimes I get 2, sometimes I get 0 (not dependent on the root item, but just seems to return the value randomly). Needless to say, with either of these values, subtracting the row of the parent item (3) -1 to get the relative index yields an index value that is invalid, because it’s negative.
Why can’t I rely on the value that -rowForItem: is returning? Why does it change according to some internal whim? At this point nothing else has changed the table, it’s just finishing its drag and drop operation, and the model is in an inconsistent state - but the table doesn’t know that yet. This is driving me insane!
—Graham
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden