2017-01-16 22 views
0

У меня есть NSCollectionView, который показывает некоторые изображения. Я внедрил NSCollectionViewDelegate, чтобы сообщить, какие элементы следует выбрать и/или выделить. Я использую запас NSCollectionViewItem, чтобы нарисовать изображения и их имена. Когда пользователь выбирает элемент, мой делегат получает сообщения об изменении состояния кульминационного:Как правильно показать текущий выбор в NSCollectionView?

- (void)collectionView:(NSCollectionView *)collectionView 
didChangeItemsAtIndexPaths:(NSSet<NSIndexPath *> *)indexPaths 
     toHighlightState:(NSCollectionViewItemHighlightState)highlightState 
{ 
    [collectionView reloadItemsAtIndexPaths:indexPaths]; 
} 

я сделать подобную вещь для didSelect/didDeselect:

- (void)collectionView:(NSCollectionView *)collectionView 
didSelectItemsAtIndexPaths:(nonnull NSSet<NSIndexPath *> *)indexPaths 
{ 
    [collectionView reloadItemsAtIndexPaths:indexPaths]; 
} 

В NSCollectionViewItem s view, я делаю следующие:

- (void)drawRect:(NSRect)dirtyRect { 
    [super drawRect:dirtyRect]; 

    NSColor* bgColor   = [[self window] backgroundColor]; 
    NSColor* highlightColor = [NSColor selectedControlColor]; 

    NSRect frame = [self bounds]; 
    NSCollectionViewItemHighlightState hlState  = [collectionViewItem highlightState]; 
    BOOL        selected = [collectionViewItem isSelected]; 
    if ((hlState == NSCollectionViewItemHighlightForSelection) || (selected)) 
    { 
     [highlightColor setFill]; 
    } 
    else 
    { 
     [bgColor setFill]; 
    } 
    [NSBezierPath fillRect:frame]; 
} 

Проблема, которую я вижу, заключается в том, что розыгрыш выделения или выделения кажется бегущим доминион Когда он делает выбор, он почти всегда находится на элементах, которые пользователь фактически выбрал (хотя по какой-то причине он часто оставляет последний элемент). Иногда он выбирает другой элемент, который пользователь не нажимал и не перетаскивал. Часто, однако, он просто не рисует.

Я добавил печать, чтобы подтвердить, что она звонит -didChangeItemsAtIndexPaths:toHighlightState: и -didSelectItemsAtIndexPaths:. Что-то я здесь делаю неправильно?

Я добавил некоторые протоколирование к -drawRect: методу зрения, и это, кажется, не вызывался на всех переходах, даже если я звоню -reloadItemsAtIndexPaths: в -didChange* методов. Почему нет?

Я также заметил, что делегат -should/didDeselectItemsAtIndexPaths:, похоже, никогда не звонит, даже если вызов вызван -should/didSelectItemsAtIndexPaths:. Почему это?

+0

попробуйте эту ссылку, возможно, это поможет вам http://stackoverflow.com/questions/2541572/selection-highlight-in-nscollectionview?rq=1 –

ответ

1

Проблема была вызвана [collectionView reloadItemsAtIndexPaths:]. Когда вы это сделаете, он удаляет существующий NSCollectionViewItem и создает новый (путем вызова вашего источника данных collectionView:itemForRepresentedObjectAt:). Это немедленно устанавливает новый элемент просмотра коллекции не выбранным (или, скорее, он не устанавливает его для выбора). Когда это произойдет, он не вызовет ваши методы should/didDeselect, потому что существующий элемент больше не существует, а новый не выбран.

Реальное решение оказалось подкласс NSCollectionViewItem и переопределить -setSelected: сделать следующее:

- (void)setSelected:(BOOL)selected 
{ 
    [super setSelected:selected]; 
    [self.view setNeedsDisplay:YES]; 
} 

Когда -drawRect: метод отображения вида вызывается, он запрашивает пункт, если он выбран и привлекает соответствующим образом.

Поэтому я мог бы полностью удалить все методы should/did/select/Deselect делегата без проблем, и все это просто сработало!

 Смежные вопросы

  • Нет связанных вопросов^_^