2

Я пишу очень простое приложение macOS, которое я хотел бы показать несколько изображений в виде коллекции. Мне не нужно какое-либо особое поведение для отображения. docs for NSCollectionViewItem говорят:Как использовать NSCollectionViewItem без подклассификации?

По умолчанию реализация этого класса поддерживает создание простого элемента, который отображает одно изображение или строку.

Это то, что я хочу. Однако я не могу найти никакой информации о том, как создать значение по умолчанию NSCollectionViewItem.

В documentation for NSCollectionView состояния:

Каждый объект источника данных необходимо реализовать следующие методы:

CollectionView: numberOfItemsInSection:

CollectionView: itemForRepresentedObjectAtIndexPath:

втором метод выше возвращает NSCollectionViewItem. Из чтения примеров я понял, что традиционный способ создания NSCollectionViewItem в данном случае назвать:

NSCollectionViewItem* newCollectionViewItem = [imageCollectionView makeItemWithIdentifier:<some identifier> 
                        forIndexPath:indexPath]; 

Проблема заключается в том, что я не понимаю, что <some identifier> должно быть. У меня нет ниба, который содержит NSCollectionViewItem, потому что я не подклассифицирую его или не настраиваю его каким-либо образом. Я попытался добавить следующее к моему источнику данных:

- (void)awakeFromNib 
{ 
    [imageCollectionView registerClass:[NSCollectionViewItem class] 
       forItemWithIdentifier:@"Image"]; 
} 

где imageCollectionView в вопросе NSCollectionView. И тогда в моем - (NSCollectionViewItem *)collectionView:itemForRepresentedObjectAtIndexPath: методе, я называю:

NSCollectionViewItem* newCollectionViewItem = [imageCollectionView makeItemWithIdentifier:@"Image" 
                        forIndexPath:indexPath]; 

Но это бросает исключение и выводит его на консоль:

2016-12-19 17: 51: 27,463 MyApp [28177: 3926764 ] - [NSNib _initWithNibNamed: bundle: options:] не удалось загрузить nibName: NSCollectionViewItem в пакете (null).

с последующим отслеживанием стека.

Как я могу создать и использовать NSCollectionViewItem, который не подклассифицирован или не изменен каким-либо образом?

+0

Вот мои мысли. № 1, вы должны указать версию Xcode, которую используете. Похоже, вы используете Xcode 7 или ниже. Были внесены изменения в метод itemForRepresentedObjectAt с момента введения Xcode 8. № 2, identifiier - это имя файла xib NSCollectionViewItem. Поэтому установка «Image» в идентификатор не имеет смысла. № 3, вы должны просто создать файл Xib файла collectionitem, за исключением этого. Было очень сложно, когда я сделал это в Swift примерно 3-4 недели назад, так как информация ограничена для Swift. –

+0

1.) Я использую Xcode 8.2 для macOS 10.11.6. 2) Как я уже упоминал, у меня нет файла xib NSCollectionViewItem, поэтому нет идентификатора, который я могу дать для файла .xib. Кроме того, документы говорят, что вы можете зарегистрировать класс вместо файла .xib, так что, вероятно, это то, что я хотел бы сделать (и пытался сделать, как вы можете видеть выше). 3) Я не понимаю этого предложения, поэтому у меня нет ответа. – user1118321

+0

К сожалению ... Я собирался написать «кроме того, что это было ужасно ...» Насколько я знаю, метод makeItemWithIdentifier был переименован в makeItem с Xcode 8. Но если вы говорите, что используете Xcode 8, я думаю, вы используют Xcode 8. Ну, удачи ... –

ответ

2

Вот очень простой пример, который использует СИБ для прототипа элемента:

@interface ViewController() 

@property (weak) IBOutlet NSCollectionView *collectionView; 

@end 

@implementation ViewController 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    NSNib *theNib = [[NSNib alloc] initWithNibNamed:@"Item" bundle:nil]; 

    [self.collectionView registerNib:theNib forItemWithIdentifier:@"item"]; 
} 

#pragma mark NSCollectionViewDataSource 

- (NSInteger)numberOfSectionsInCollectionView:(NSCollectionView *)inCollectionView { 
    return 1; 
} 

- (NSInteger)collectionView:(NSCollectionView *)inCollectionView numberOfItemsInSection:(NSInteger)inSection { 
    return 10; 
} 

- (NSCollectionViewItem *)collectionView:(NSCollectionView *)inCollectionView itemForRepresentedObjectAtIndexPath:(NSIndexPath *)inIndexPath { 
    NSCollectionViewItem *theItem = [inCollectionView makeItemWithIdentifier:@"item" forIndexPath:inIndexPath]; 
    NSTextField *theLabel = (NSTextField *)theItem.view; 

    theLabel.stringValue = [NSString stringWithFormat:@"%d.%d", (int)inIndexPath.section, (int)inIndexPath.item]; 
    return theItem; 
} 

@end 

НСБ содержит только NSCollectionViewItem с текстовым полем в виде.

Добавление: Я думаю, вы должны создать NSCollectionViewItem.xib для варианта RegisterClass. Контроллер представления будет искать NIB с его именем класса, если вы не создадите его вид вручную в loadView.Таким образом, вы не можете использовать простой NSCollectionViewItem без NIB для регистрации класса, потому что makeItemWithIdentifier:forIndexPath: получит доступ к представлению элемента.

+0

Но зачем нужен НИБ? Почему мы не можем использовать '-registerClass:' вместо '-registerNib:'? И почему вам нужно добавить текстовое поле в качестве представления? Документы говорят, что реализация по умолчанию включает текстовое поле и изображение. – user1118321

+0

Я добавил добавление. – clemens

+0

@ user1118321, пожалуйста, проверьте следующую ссылку, она решит ваше замешательство в отношении -registerClass: вместо -registerNib:?: http://stackoverflow.com/questions/33396623/uicollectionviewcell-register-class-fails-but-register-nib- works – Zulqarnain