2015-02-18 3 views
1

В моем приложении Mac у меня есть NSCollectionView с включенным multi select. В моем приложении возможность выбора более одного элемента является нормой, и при нажатии кнопки cmd при нажатии на несколько элементов происходит разочарование некоторых пользователей, и большинство из них не понимают, что они могут это сделать. (Я получаю много запросов функций для multi select).Изменение поведения выбора NSCollectionView

Итак, я хочу, чтобы изменить поведение, так что:

  • , когда пользователь нажимает на второй элемент, первый элемент остается выбранным (без необходимости проведения CMD)
  • Когда пользователь нажимает кнопку выбранный элемент, элемент выключенной

Я попытался переопределение setSelected на моем собственном подклассе NSCollectionViewItem так:

-(void)setSelected:(BOOL)flag 
{ 
    [super setSelected:flag]; 
    [(MyView*)[self view] setSelected: flag]; 
    [(MyView*)[self view] setNeedsDisplay:YES]; 
} 

Вызывающий супер наборВыбранный необходим, чтобы убедиться, что просмотр коллекции функционирует правильно, но также, похоже, отвечает за поведение по умолчанию.

Что мне делать вместо этого?

ответ

1

Вы можете попробовать перехватить все события, связанные с левым-указательным курсом, с помощью локального монитора событий. Внутри этого блока вы затем будете работать, если щелчок произошел в вашем представлении коллекции. Если это так, создайте новое событие, которое имитирует перехваченное событие, но добавьте в маску ключа команды, если оно еще не присутствует. Затем в конце блока верните свое событие, а не тот, который вы перехватили. Представление вашей коллекции будет вести себя так, как если бы пользователь нажал клавишу команды, даже если они этого не сделали!

Я быстро поработал с этим в очень простом демонстрационном приложении, и это похоже на многообещающий подход - хотя я ожидаю, что вам придется обсудить несколько gotchas по пути.

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { 


    [NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskFromType(NSLeftMouseDown) 
      handler:^NSEvent *(NSEvent *originalEvent) { 

     // Did this left down event occur on your collection view? 
     // If it did add in the command key 

     NSEvent *newEvent = 
      [NSEvent 
       mouseEventWithType: NSLeftMouseDown 
       location: originalEvent.locationInWindow 
       modifierFlags: NSCommandKeyMask // I'm assuming it's not already present 
       timestamp: originalEvent.timestamp 
       windowNumber: originalEvent.windowNumber 
       context: originalEvent.context 
       eventNumber: originalEvent.eventNumber 
       clickCount: originalEvent.clickCount 
       pressure:0]; 

     return newEvent; // or originalEvent if it's nothing to do with your collection view 
    }]; 
} 

Edit (на вопрос автора):

Это решение так сильно на основе оригинальный ответ, что этот ответ заслуживает кредита (не стесняйтесь редактировать)

Вы можете также перехватывать мыши путем подкласса класса NSCollectionView и переопределения mousedown следующим образом:

@implementation MyCollectionView 

-(void) mouseDown:(NSEvent *)originalEvent { 

    NSEvent *mouseEventWithCmd = 
     [NSEvent 
      mouseEventWithType: originalEvent.type 
      location: originalEvent.locationInWindow 
      modifierFlags: NSCommandKeyMask 
      timestamp: originalEvent.timestamp 
      windowNumber: originalEvent.windowNumber 
      context: originalEvent.context 
      eventNumber: originalEvent.eventNumber 
      clickCount: originalEvent.clickCount 
      pressure: originalEvent.pressure]; 

    [super mouseDown: mouseEventWithCmd]; 
} 

@end 
+0

Это действительно работает, но, к сожалению, я ntercepting на уровне событий мыши и добавление cmd ко всем кликам над NSCollectionView ломает еще одну важную особенность моего приложения. В моем представлении коллекции есть другие элементы управления, которые добавляют cmd к событию мыши, изменяя их поведение. Я могу найти способ распознать событие мыши, основанное на его местоположении пикселей. Это нормально для общего контроля, но по мере того, как суб-элементы управления перемещаются, я не думаю, что это практично. –

+0

Это решение будет работать для других, но у кого нет других элементов управления, требующих событий мыши в их NSCollectionView. –

+0

Получил его, используя измененную версию того, что вы предложили. Надеюсь, вы не против, но я добавил его к вашему ответу, поскольку вы заслуживаете большей части кредита. Не стесняйтесь редактировать ответ, чтобы сделать его более кратким и полезным для будущих людей. –

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