2
votes

I have the following set-up:

A Window that has a splitView in which I display I NSCollectionView in the left view and a detailView in the right view. Both views are set-up in separate xibs. Furthermore I have a Datacontroller (of class NSArrayController) that manages a mutable Array of NSMutableDictionaries (moviesForChoice). The dataController is set-up as application delegate. The movie objects in the array have properties like (name, plot, genre etc.)

so far so good...

In the xib for the NScollectionview I bound a NSArraycontroller content property to my datacontroller via Application.delegate.moviesForChoice The collectionView accesses the arraycontroller.arrrangedObjects and arraycontroller.selectionIndexes. This works fine the contents are displayed and the selection works fine in the collectionview (my collectionviewItem renders a selection color)

In the xib for the detailView I want to display information for the selected object in the collectionview. Therefore I also added an arraycontroller to the xib, bound the content aray to Application.delegate.moviesForChoice and bound the NSTextfields in the view to e.g. arraycontroller.selection.name

Here comes my issue: everytime I open the window with the two xibs, my collectionview displays all movies that are for choice correctly, and the detailview displays the information for the 1st object in my collectionview. Whenever I click on a different movie in the collectionView the res. item renders a selection color, but the detailView doesn't update.

My understanding of it would be that the DataController is not informed about updates in the selectionIndexes and can therefore not trigger an update in the detailView. Correct me if I'm wrong...

To remedy this I tried to bind the selectionIndexes property of the arraycontroller in the collectionView xib to Application.delegate.moviesForChoice.selecionIndexes but this failed with: addObserver:forKeyPath:options:context:] is not supported. Key path: selectionIndexes

I could imagine that this means that the datacontroller is not KVO compliant for my Array moviesForChoice, but I implemented the following methods for it:

  -(void)insertObject:(NSDictionary *)dict inMoviesForChoiceAtIndex:(NSUInteger)index {
    [moviesForChoice insertObject:dict atIndex:index];
}

 -(void)removeObjectFromMoviesForChoiceAtIndex:(NSUInteger)index {
        [moviesForChoice removeObjectAtIndex:index];
    }

-(void)setMoviesForChoice:(NSMutableArray *)a {
    moviesForChoice = a;
}

-(NSArray*)moviesForChoice {
    return moviesForChoice;
}

-(NSUInteger)countOfMoviesForChoice
{
    return [moviesForChoice count];
}

- (void)addMovieForChoiceObject:(Movie *)anObject
{
    [moviesForChoice addObject:anObject];
}

So where am I wrong? How do I correctly bind to the selectionIndexes?

You help is much appreciated! M

2

2 Answers

1
votes

a clever way to deal with selection updates is to add an intermediary object which will update only with selection i.e. in your case I would have created within the former "interface builder" an intermediary "Object Controller" bound to the current selected object. Then all the related information to the currently selected objet would have to be bound to this single object instance (which should include automatic updates while it is changed). This said I also experienced the case where, for no apparent reasons, the interface objet did loaded but the related bound items did not…(= were not updated), in that case a pretty good solution is to work with observers for catching generic action instead of dealing with per-object-click assignment. A typical action being the change of the selectionIndex.

[listArrayController addObserver:self forKeyPath:@"selectionIndexes" options:NSKeyValueObservingOptionNew context:nil];  

Then in your class:

 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if([keyPath isEqualTo:@"selectionIndexes"])
    {
/* DO STUFF HERE LIKE BINDING THE OBJECT TO THE CURRENT SELECTION */
    }
}
0
votes

Unfortunately, no one had an answer or maybe I didn't explain myself good enough.

So I introduced a new variable in my dataController that is filled by the collectionViewItem whenever it is clicked and I bound the detailview to the object in the variable.

It's manual, I know, but it does the trick.

If anyone comes up with a better answer, feel free to share. I'd appreciate it.