Один из подходов, который я использовал, заключается в том, чтобы не пытаться применять действия контекстного меню к одному конкретному элементу, на который было нажато, но к выбранным элементам. И я делаю элемент clicked-on, добавляющий себя к выбору.
Я использовал пользовательский вид для просмотра элемента коллекции. У пользовательского класса представления есть выход, item
, его элемент просмотра коллекции, который я подключаю в NIB. Он также отменяет -rightMouseDown:
иметь элемент добавить себя к выбору:
- (void) rightMouseDown:(NSEvent*)event
{
NSCollectionView* parent = self.item.collectionView;
NSUInteger index = NSNotFound;
NSUInteger count = parent.content.count;
for (NSUInteger i = 0; i < count; i++)
{
if ([parent itemAtIndex:i] == self.item)
{
index = i;
break;
}
}
NSMutableIndexSet* selectionIndexes = [[parent.selectionIndexes mutableCopy] autorelease];
if (index != NSNotFound && ![selectionIndexes containsIndex:index])
{
[selectionIndexes addIndex:index];
parent.selectionIndexes = selectionIndexes;
}
return [super rightMouseDown:event];
}
Если вы предпочитаете, а не добавление элемента к выбору, вы можете проверить, если он уже в отборе. Если это так, не изменяйте выбор. Если это не так, замените выбор только одним элементом (что делает его единственным выбранным элементом).
В качестве альтернативы вы можете установить контекстное меню в представлениях элементов, а не в виде коллекции. Затем пункты меню могут быть нацелены либо на элемент, либо на элемент коллекции.
Наконец, вы можете подкласса NSCollectionView
и переопределить -menuForEvent:
. Вы все равно вызовете до super
и вернете меню, которое оно возвращает, но вы можете воспользоваться возможностью для записи события и/или элемента в его местоположении. Для того, чтобы определить, что вы могли бы сделать что-то вроде:
- (NSMenu*) menuForEvent:(NSEvent*)event
{
_clickedItemIndex = NSNotFound;
NSPoint point = [self convertPoint:event.locationInWindow fromView:nil];
NSUInteger count = self.content.count;
for (NSUInteger i = 0; i < count; i++)
{
NSRect itemFrame = [self frameForItemAtIndex:i];
if (NSMouseInRect(point, itemFrame, self.isFlipped))
{
_clickedItemIndex = i;
break;
}
}
return [super menuForEvent:event];
}
прекрасный !!! Спасибо огромное! –
Это слишком сложно. Вы пробовали установить в меню меню вашего коллекционного представления меню из файла nib? Задайте свой объект контроллера в качестве делегата для меню. Каждый раз, когда вызывается меню, обновляйте свое меню в соответствии с выбором в представлении коллекции. – iljawascoding
Мне очень нравится подкласс подкласса «NSCollectionView» - обеспечивает хорошую согласованность поведения с «NSTableView». –