Re: CoreData with OutlineView collapses items on fetch
Re: CoreData with OutlineView collapses items on fetch
- Subject: Re: CoreData with OutlineView collapses items on fetch
- From: peter ljunglöf <email@hidden>
- Date: Tue, 13 Jan 2009 22:51:03 +0100
Hi Ron,
thanks for the information. Your explanation sounds reasonable and it
also explains why the selection is removed (since the old TreeNode is
removed), and why the delegate method outlineViewItemDidCollapse (and
similar) is not triggered (since there is no "collapse", just a new
fresh TreeNode).
So, there was a change in the behaviour of NSTreeController between
10.5.5 and 10.5.6. Before it always returned the old TreeNode, but now
it (sometimes) creates a new TreeNode - e.g., if it is deeply nested.
Do you know if this new behaviour is intentional?
The only solution I can see is to go through all items in the
OutlineView and record which of them are expanded or not, and record
the curent selection. Then call [TreeController fetch], and then go
through the items again, reexpanding and reselecting if necessary.
This means that using CoreData suddenly requires much more coding than
before.
/Peter Ljunglöf
13 jan 2009 kl. 20.45 skrev Ron Lue-Sang:
Hi Peter,
I only skimmed through your description/question, but I'm reasonable
sure I know what you're asking and what the answer is.
The outlineView identifies its items by pointer comparison. So two
objects that are logically the same can show up in the tree
together, but they can have different expansion state associated
with them. For an outlineView bound to a treeController, the
outlineView's items are NSTreeNodes vended by the treeController.
If you start out with A containing B and its descendants C and D,
and then refresh managedObject A, the treeController sees this
1) A no longer has child objects
2) A has a new set of child objects
The treeController will see step one and nuke the treeNodes
associated with B, C and D, since they're gone now. Then when A has
its childObjects relationship filled in again, the outlineView knows
that the outlineView item for A needs to be reloaded, so it'll ask
the treeController for item A's child items. These will be a new set
of treeNodes, including B.
What's happening is the treeController doesn't know that old B will
become new B later. So it returns a different NSTreeNode instance to
the outlineView for its item. The outlineView sees the new instance
and shows it collapsed by default.
If you know you're going to do an operation like this, you can hang
on to the indexPath of the nodes you want to expand, and just re-
expand them when the operation is over.
Hope that helps.
On Jan 13, 2009, at 2:33 AM, peter ljunglöf wrote:
Hi,
After upgrading to 10.5.6, I got a problem with NSOutlineView and
NSTreeController in my CoreData application. When executing fetch:
on the NSTreeController, deeply nested items (nesting level>=2)
collapses in the NSOutlineView.
I created a minimal XCode project with the same problem, it can be
downloaded from
http://heatherleaf.se/temp/OutlineBug.zip
Open in XCode (I've tried 3.1.1 and 3.1.2), compile and run. Create
some nested items (double-click to rename the item), select the
topmost item and then click the "Fetch" button. E.g., if I create
the following items (where "v" is the expanded triangle and ">" is
the collapsed triangle):
+-----------------------+
| v A |
| v B |
| v C |
| D |
+-----------------------+
Select the A item, and the click "Fetch", I get the following result:
+-----------------------+
| v A |
| > B |
| |
| |
+-----------------------+
Depending on the nestings and which item is selected, the selection
sometimes changes, and sometimes everything is deselected.
Also, none of the following delegate methods get called:
outlineView:shouldCollapseItem:
outlineViewItemWillCollapse:
outlineViewItemDidCollapse:
Does anyone know what the problem is and how I can avoid collapsing
my outline views? I did not have this problem in 10.5.5.
The example project is really simple. I created a new CoreData
Application project. Added one attribute "name" and two
relationships "children" and "parent" (inverses) to the data model.
I did not touch the code at all.
In IB, I added a NSTreeController, with I set to Entity mode,
children key path "children" and fetch predicate "parent==nil".
Bound the Managed Object Context to
OutlineBug_AppDelegate.managedObjectContext.
Then I added a NSOutlineView with one column, and bound that
column's Value to TreeController.arrangedObjects.name.
Finally I added three buttons: Fetch, Remove and Add Child, and
bound their sent actions to the TreeController's fetch:, remove:,
and addChild: methods.
That's all.
regards,
Peter Ljunglöf
PS. My original project is of course larger, and can be found at http://code.google.com/p/kronox/
, if someone's interested...
--------- ----- --- -- -- - - - - - - -
- -
peter ljunglöf (http://www.ling.gu.se/~peb)
_______________________________________________
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
--------------------------
RONZILLA
--------- ----- --- -- -- - - - - - - - - -
peter ljunglöf (http://www.ling.gu.se/~peb)
_______________________________________________
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