我正在尝试使用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,所以不是问题。
答案 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来修复,我还不确定。