Re: Tracking an NSArrayController's selection [SOLVED]
Re: Tracking an NSArrayController's selection [SOLVED]
- Subject: Re: Tracking an NSArrayController's selection [SOLVED]
- From: Camillo Lugaresi <email@hidden>
- Date: Tue, 3 Jan 2006 22:32:06 +0100
Even though this thread did not receive much attention, I want to
share the solution that I eventually found.
-- The objective --
I have a two-tiered master-details interface; let's say the first
tier is groups, and the second tier is items. There is a table view
for groups, and a table view for items inside the selected group;
each table view is bound to an array controller. I need to track the
currently selected group, and, for each group, its currently selected
item, and I need to do it by saving the numeric index of each,
because that's what the back-end wants.
-- The problem --
I bound the selectionIndexes of the group array controller to a key
in the master controller (selectedGroupIdx), and the selectionIndexes
of the item array controller to the key path
selection.selectedItemIdx in the group controller, while its content
is bound to selection.items.
However, there turned out to be a problem in the order the accessors
are called. Here is an example log of the accessors called when
changing the selected group from group A to group B:
(A is selected, user clicks B)
set B sel.item: 4 -> null (ignored)
get B sel.item: 4
set B sel.item: 4 -> 0
get B sel.item: 0
set sel.group: A -> B
get sel.group: B
The selected item in B is set to 0 because A had less than 5 items,
and the item array controller thinks that the index 4 is out of
bounds. When A has 5 or more items, the controller accepts 4 as the
selection index for B. In other words, while setting the selection
for B, the item array controller is still looking at the contents of
A. This is probably because the group array controller tells the item
ac to update its selection before it tells it to update its content;
I believe this is a bug in NSArrayController.
-- The solution --
Instead of binding the selectionIndexes of the item array controller
to selection.selectedItemIdx in the group array controller, I bind it
to selectedItemIdx in the master controller. The master controller
class sets this key as dependent on selectedGroupIdx, and implements
accessors to get and set it for the currently selected group. This
method ensures that the item array controller's selection is changed
after its content has been updated.
An example log of the accessor calls with this new method:
(A is selected, user clicks B)
set A sel.item: 2 -> null (ignored)
get A sel.item: 2
set sel.group: A -> B
get B sel.item: 4
get sel.group: B
As mentioned in one of my previous messages, it is important to
disable the "avoids empty selection" option for the controller: this
lets the accessor ignore the initial attempt to set the item
selection of the group being deselected to empty. Of course, if it
was necessary to support empty selections then this work-around would
have to be modified, probably by also binding the content of the item
array controller through the master controller instead of through the
selection of the group array controller.
I hope this information will be useful to others.
Camillo Lugaresi, tamer of bindings ;-)
_______________________________________________
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