2

在我的 Mac 应用程序中,我有一个启用了多选的 NSCollectionView。在我的应用程序中,能够选择多个项目是常态,并且在单击选择多个项目时必须按 cmd 让一些用户感到沮丧,并且大多数用户没有意识到他们可以做到这一点(我收到了很多要求的功能请求多选)

所以,我想改变行为,以便:

  • 当用户单击第二个项目时,第一个项目保持选中状态(无需按住 cmd)
  • 当用户单击所选项目时,该项目被取消选择

我尝试在我自己的 NSCollectionViewItem 子类上覆盖 setSelected,如下所示:

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

需要调用 super setSelected 以确保集合视图正常运行,但它似乎也是导致默认行为的原因。

我应该怎么做?

4

1 回答 1

1

您可以尝试使用本地事件监视器拦截所有鼠标左键事件。在此块中,您将确定点击是否发生在您的收藏视图上。如果确实如此,请创建一个新事件来模仿您截获的事件,但如果它不存在,则添加命令键掩码。然后,在块的末尾返回您的事件,而不是您拦截的事件。您的集合视图将表现得好像用户按下了命令键,即使他们没有!

我在一个非常简单的演示应用程序中快速完成了这一点,它看起来是一种很有前途的方法——尽管我希望你在此过程中必须协商一些问题

- (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
    }];
}

编辑(由问题作者):

该解决方案非常基于原始答案,因此该答案值得称赞(随意编辑)

您还可以通过继承 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
于 2015-02-18T19:28:53.880 回答