I am trying to nest NSCollection view inside of one another. I have tried to create a new project using the Apple Quick Start Guide as a base.
I start by inserting a collection view into my nib, to the view that is automatically added I drag another collection view onto it. The sub-collection view added gets some labels. Here is a picture of my nib:
I then go back and build my models: My second level model .h is
@interface BPG_PersonModel : NSObject
@property(retain, readwrite) NSString * name;
@property(retain, readwrite) NSString * occupation;
@end
My First level model .h is:
@interface BPG_MultiPersonModel : NSObject
@property(retain, readwrite) NSString * groupName;
@property(retain,readwrite) NSMutableArray *personModelArray;
-(NSMutableArray*)setupMultiPersonArray;
@end
I then write out the implementation to make some fake people within the first level controller(building up the second level model): (edit) remove the awakefromnibcode
/*- (void)awakeFromNib {
BPG_PersonModel * pm1 = [[BPG_PersonModel alloc] init];
pm1.name = @"John Appleseed";
pm1.occupation = @"Doctor";
//similar code here for pm2,pm3
NSMutableArray * tempArray = [NSMutableArray arrayWithObjects:pm1, pm2, pm3, nil];
[self setPersonModelArray:tempArray];
} */
-(NSMutableArray*)setupMultiPersonArray{
BPG_PersonModel * pm1 = [[BPG_PersonModel alloc] init];
pm1.name = @"John Appleseed";
pm1.occupation = @"Doctor";
//similar code here for pm2,pm3
NSMutableArray * tempArray = [NSMutableArray arrayWithObjects:pm1, pm2, pm3, nil];
return tempArray;
}
Finally I do a similar implementation in my appdelegate to build the multiperson array
- (void)awakeFromNib {
self.multiPersonArray = [[NSMutableArray alloc] initWithCapacity:1];
BPG_MultiPersonModel * mpm1 = [[BPG_MultiPersonModel alloc] init];
mpm1.groupName = @"1st list";
mpm1.personModelArray = [mpm1 setupMultiPersonArray];
(I'm not including all the code here, let me know if it would be useful.)
I then bind everything as recommended by the quick start guide. I add two nsarraycontrollers with attributes added to bind each level of array controller to the controller object
I then bind collectionview to the array controller using content bound to arrangedobjects
Finally I bind the subviews:
with the grouptitle label to representedobject.grouptitle object in my model
then my name and occupation labels to their respective representedobjects
I made all the objects kvo compliant by including the necessary accessor methods
I then try to run this app and the first error I get is: NSCollectionView item prototype must not be nil.
(edit) after removing awakefromnib from the first level model I get this
Has anyone been successful at nesting nscollection views? What am I doing wrong here? Here is the complete project zipped up for others to test:
thanks for the help
EDITED:
I finally contacted apple technical support to see if they could help me out. Response from them is:
Cocoa bindings will only go so far, until you need some extra code to make it all work.
When using arrays within arrays to populate your collection view the bindings will not be transferred correctly to each replicated view without subclassing NSCollectionView and overriding newItemForRepresentedObject and instantiating the same xib yourself, instead of using the view replication implementation provided by NSCollectionView.
So in using the newItemForRepresentedObject approach, you need to factor our your NSCollectionViewItems into separate xibs so that you can pass down the subarray of people from the group collection view to your inner collection view.
So for your grouped collection view your override looks like this:
- (NSCollectionViewItem *)newItemForRepresentedObject:(id)object { BPG_MultiPersonModel *model = object; MyItemViewController *item = [[MyItemViewController alloc] initWithNibName:@"GroupPrototype" bundle:nil]; item.representedObject = object; item.personModelArray = [[NSArrayController alloc] initWithContent:model.personModelArray]; return item; }
And for your inner collection subclass your override looks like this:
- (NSCollectionViewItem *)newItemForRepresentedObject:(id)object { PersonViewController *item = [[PersonViewController alloc] initWithNibName:@"PersonPrototype" bundle:nil]; item.representedObject = object; return item; }
here is a sample project that they sent back to me -
I am still unable to get this to work with my own project. Can the project they sent back be simplified further?