更改NSCollectionView的选择行为

时间:2015-02-18 17:57:57

标签: cocoa nscollectionview nscollectionviewitem

在我的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是确保集合视图正常运行所必需的,但它似乎也是导致默认行为的原因。

我该怎么办?

1 个答案:

答案 0 :(得分: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