objective-cmacosautolayoutnscollectionviewnscollectionviewitem

NSCollectionView is drawing NSCollectionViewItems over each other


My NSCollectionView is drawing my NSCollection items over each other. UPDATE: I have added a sample project GitHub Sample Project

UPDATE: This has changed somewhat When the app first launches it looks like this

UPDATE My current example has two views which are currently in there own nib files, with dedicated NScollectionViewItem objects they are currently the same for testing. I basically have a NSCollectionViewItem which has as it's child a view with the NSTextField in it. With all of the constraints.

For the Collection View it is setup as a Grid Controller, and ideally, I would like to have 1 column.

In order to load it with Data I made my ViewController the NSCollectionViewDataSource, and implemented the - (NSInteger)collectionView:(NSCollectionView *)collectionView numberOfItemsInSection:(NSInteger)section and - (NSCollectionViewItem *)collectionView:(NSCollectionView *)collectionView itemForRepresentedObjectAtIndexPath:(NSIndexPath *)indexPath

UPDATED CODE Full Code included:

- (void)viewDidLoad {
    [super viewDidLoad];

    // Do any additional setup after loading the view.

    [collectionView registerClass:ItemOne.class forItemWithIdentifier:@"Item1"];
    [collectionView registerClass:ItemTwo.class forItemWithIdentifier:@"Item2"];

    cellArray = [@[@"Item1", @"Item2", @"Item1", @"Item2", @"Item1"] mutableCopy];
}


- (void)setRepresentedObject:(id)representedObject {
    [super setRepresentedObject:representedObject];

    // Update the view, if already loaded.
}

#pragma mark - NSCollectionViewDatasource -
- (NSInteger)collectionView:(NSCollectionView *)collectionView
 numberOfItemsInSection:(NSInteger)section {

    // We are going to fake it a little.  Since there is only one section
    NSLog(@"Section: %ld, count: %ld", (long)section, [cellArray count]);

    return [cellArray count];
}

- (NSCollectionViewItem *)collectionView:(NSCollectionView *)collectionView
 itemForRepresentedObjectAtIndexPath:(NSIndexPath *)indexPath {

    NSLog(@"IndexPath: %@, Requested one: %ld", indexPath, [indexPath item]);
    NSLog(@"Identifier: %@", [cellArray objectAtIndex:[indexPath item]]);

    NSCollectionViewItem *theItem = [collectionView makeItemWithIdentifier:[cellArray objectAtIndex:[indexPath item]] forIndexPath:indexPath];

    return theItem;
}

UPDATE The ItemOne and ItemTwo classes are both empty classes, the nib for each has a NSCollectionViewItem which in turn has a view, with label. The View is connected to the NSCollectionViewItem by the view property in NSCollectionViewItem. There are currently no constraints except for the default ones

The NSCollectionView grid is set up as follows:

Layout: Grid Dimensions: Max Rows: 0 Max Columns: 1 Min Item Size: Width: 250 Height: 150 Max Item Size: Width: 250 Height: 150

This is the code for setting up the whole thing, at this point not tying it to a data source.

It seems that no matter what I change the settings or even changing the CollectionView type to Flow doesn't change anything, it looks the same.

I have been approaching this as an AutoLayout issue because originally there were some auto layout issues, but those have all been resolved.

Any help would be greatly appreciated.


Solution

  • The data array should hold data instead of NSCollectionViewItems. In collectionView:itemForRepresentedObjectAtIndexPath: you call makeItemWithIdentifier:forIndexPath:. Call registerClass:forItemWithIdentifier: or registerNib:forItemWithIdentifier: to register your class or nib.

    More info in the documentation of NSCollectionView, collectionView:itemForRepresentedObjectAtIndexPath: and makeItemWithIdentifier:forIndexPath:.

    EDIT:

    There are two ways to provide a NSCollectionViewItem.

    registerClass:forItemWithIdentifier:. When the collection view needs a new item, it instatiates this class. NSCollectionViewItem is a subclass of NSViewController and NSViewController looks for a nib with the same name as the class. The NSCollectionViewItem is the owner of the nib.

    registerNib:forItemWithIdentifier:. When the collection view needs a new item, it loads this nib. The NSCollectionViewItem is a top level object in the nib.

    You mixed registerClass:forItemWithIdentifier: with a xib for use with registerNib:forItemWithIdentifier:. Use registerNib:forItemWithIdentifier: or fix the xib.