以编程方式使用数据源创建NSCollectionView

时间:2016-03-26 02:23:06

标签: objective-c macos cocoa nscollectionview

我正在尝试使用NSCollectionView以编程方式创建NSCollectionViewDataSource

代码非常简单:

self.collectionView = [[NSCollectionView alloc] init];
// Add collection view to self.view etc. 
self.collectionView.dataSource = self;
[self.collectionView registerClass:[NSCollectionViewItem class] forItemWithIdentifier:@"test"]
self.collectionView.collectionViewLayout = gridLayout;
[self.collectionView reloadData]

这导致以下方法被调用(如果我没有明确设置collectionViewLayout属性,这两个人也不会被调用):

- (NSInteger)numberOfSectionsInCollectionView:(NSCollectionView*)collectionView
- (NSInteger)collectionView:(NSCollectionView*)collectionView numberOfItemsInSection:(NSInteger)section

但是,永远不会调用collectionView:itemForRepresentedObjectAtIndexPath:。为了确保调用最后一个数据源方法,我还需要做些什么吗?我确保两个计数调用返回> 0,所以不是问题。

2 个答案:

答案 0 :(得分:7)

所以看起来问题实际上是我没有在NSScrollView中包装NSCollectionView。这可能与错误地完成布局(因此不会从数据源请求项目)有关,如果它没有包含在滚动视图中。

答案 1 :(得分:2)

过去几天我一直在研究不同的场景,我敢说使用NSScrollView,或许没有,几乎没有区别。无论有没有scrollView,我最终都遇到了相同的错误和限制。

“旧学校”和新奇的collectionView之间的选择有什么影响。 “旧学校”是指设置itemPrototype和contents属性,如下所示:

    NSCollectionView *collectionView = [[NSCollectionView alloc] init];
    collectionView.itemPrototype = [TBCollectionViewItem new];
    collectionView.content = self.collectionItems;

    NSInteger index = 0;
    for (NSString *title in _collectionItems) {
        NSIndexPath *path = [NSIndexPath indexPathForItem:index inSection:0];
        TBCollectionViewItem *item = [collectionView makeItemWithIdentifier:@"Test" forIndexPath:path];
        item.representedObject = title;
        index++;
    }
    // Plays well with constraints

新学校,就这些方面:

NSCollectionView *collectionView = [[NSCollectionView alloc] init];
collectionView.identifier = TBCollectionViewIdentifier;

[collectionView registerClass:[TBCollectionViewItem class] forItemWithIdentifier:TBCollectionViewItemIdentifier]; //register before makeItemWithIdentifier:forIndexPath: is called.
TBCollectionViewGridLayout *gridLayout = [TBCollectionViewGridLayout collectionViewGridLayout:NSMakeSize(250, 100)]; //getting the contentSize from the scrollView does not help
collectionView.collectionViewLayout = gridLayout;
collectionView.dataSource = self;

现在,您可能已经注意到必须在makeItemWithIdentifier:forIndexPath之前调用registerClass:的注释。实际上,这意味着在设置.dataSource之前调用registerClass:而在代码中首先设置.dataSource。文档声明:

  

虽然您可以随时注册新项目,但在注册相应项目之前,不得调用makeItemWithIdentifier:forIndexPath:方法。

我希望我可以说通过切换这两行,所有布局问题都将得到解决。不幸的是,我发现.collectionViewLayout / .dataSource组合是(自动)布局灾难的一个秘诀。是否可以通过从NSCollectionViewGridLayout切换到flowLayout来修复,我还不确定。

相关问题