2016-03-26 7 views
2

Я пытаюсь создать NSCollectionView программно, используя NSCollectionViewDataSource.Создание NSCollectionView с datasource programatically

Код очень прост:

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: никогда не вызывается. Есть ли что-то еще, что мне нужно сделать, чтобы убедиться, что последний метод источника данных вызван? Я убедился, что два вызова count возвращаются> 0, так что это не проблема.

+0

попробуйте перейти от gridLayout к новому (я забыл, что он называется). Макет сетки - это макет старого стиля. – pickwick

+0

'NSCollectionViewGridLayout' доступен в 10.11 с новым методом источника данных, поэтому он должен работать. Попробовал изменить его на 'NSCollectionViewFlowLayout', и он до сих пор не назвал' itemForRepresentedObjectAtIndexPath', к сожалению. – kevinlindkvist

ответ

7

Похоже, что проблема заключалась в том, что я не собирал NSCollectionView в NSScrollView. Это, вероятно, связано с неправильным оформлением макета (поэтому элементы не запрашиваются из источника данных), если он не завернут в виде прокрутки.

1

Я работал в разных сценариях в прошлые дни, и осмелюсь сказать, что использование NSScrollView или нет, практически не имеет разницы. С scrollView или без него, я столкнулся с теми же ошибками и ограничениями.

Что имеет огромное значение, так это выбор между «старой школой» и новообретенной коллекциейView. Под «старой школы», я имею в виду установление itemPrototype и содержимое свойства, что-то вроде этого:

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; 

Теперь, вы заметили комментарий, что RegisterClass : должно быть вызвано до makeItemWithIdentifier: forIndexPath. На практике это означает вызов registerClass: перед установкой .dataSource, тогда как в вашем коде вы сначала устанавливаете .dataSource. Государство документы:

Хотя вы можете зарегистрировать новые элементы в любое время, вы не должны вызывать makeItemWithIdentifier: forIndexPath: метод только после регистрации соответствующего пункта.

Я бы хотел сказать, что, переключив эти две линии, все проблемы макета будут решены. К сожалению, я обнаружил, что комбинация .collectionViewLayout/.dataSource - это рецепт катастрофы макета. Может ли это быть исправлено путем переключения с NSCollectionViewGridLayout на flowLayout, я еще не уверен.

+0

зарегистрируйте наконечник после установки источника данных - это то, что исправлено для меня. Благодаря! –