使用NSStatusItem拖放

Bry*_*yle 15 cocoa drag-and-drop nsstatusitem

我正在尝试编写一个应用程序,允许用户从Finder中拖动文件并将其拖放到NSStatusItem.到目前为止,我已经创建了一个实现拖放界面的自定义视图.当我将这个视图添加为它的子视图时NSWindow,一切正常 - 鼠标光标给出了适当的反馈,当删除时我的代码被执行.

但是,当我使用相同的视图作为NSStatusItem's视图时,它的行为不正确.鼠标光标提供适当的反馈,表明文件可以被删除,但是当我删除文件时,我的丢弃代码永远不会被执行.

我需要做些什么特别的事情来实现拖放NSStatusItem吗?

Rob*_*ger 30

我终于开始测试这个了,它运行得很好,所以你的代码肯定有问题.

这是一个允许拖动的自定义视图:

@implementation DragStatusView

- (id)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        //register for drags
        [self registerForDraggedTypes:[NSArray arrayWithObjects: NSFilenamesPboardType, nil]];
    }

    return self;
}

- (void)drawRect:(NSRect)dirtyRect
{
    //the status item will just be a yellow rectangle
    [[NSColor yellowColor] set];
    NSRectFill([self bounds]);
}

//we want to copy the files
- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender
{
    return NSDragOperationCopy;
}

//perform the drag and log the files that are dropped
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender 
{
    NSPasteboard *pboard;
    NSDragOperation sourceDragMask;

    sourceDragMask = [sender draggingSourceOperationMask];
    pboard = [sender draggingPasteboard];

    if ( [[pboard types] containsObject:NSFilenamesPboardType] ) {
        NSArray *files = [pboard propertyListForType:NSFilenamesPboardType];

        NSLog(@"Files: %@",files);
    }
    return YES;
}


@end
Run Code Online (Sandbox Code Playgroud)

以下是您创建状态项的方法:

NSStatusItem* item = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength] retain];

DragStatusView* dragView = [[DragStatusView alloc] initWithFrame:NSMakeRect(0, 0, 24, 24)];
[item setView:dragView];
[dragView release];
Run Code Online (Sandbox Code Playgroud)

  • 真棒!但我如何处理点击此视图和显示菜单? (3认同)

Luk*_*ieß 11

自Yosemite以来,用于设置视图的方法NSStatusItem已被弃用,但幸运的是,使用新NSStatusItemButton属性有一个更好的方法NSStatusItem:

- (void)applicationDidFinishLaunching: (NSNotification *)notification {
    NSImage *icon = [NSImage imageNamed:@"iconName"];
    //This is the only way to be compatible to all ~30 menu styles (e.g. dark mode) available in Yosemite
    [normalImage setTemplate:YES];
    statusItem.button.image = normalImage;

    // register with an array of types you'd like to accept
    [statusItem.button.window registerForDraggedTypes:@[NSFilenamesPboardType]];
    statusItem.button.window.delegate = self;
Run Code Online (Sandbox Code Playgroud)

}

- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender {
    return NSDragOperationCopy;
}

- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender {
  //drag handling logic
}
Run Code Online (Sandbox Code Playgroud)

请注意,button酒店仅在10.10开始提供,如果您支持10.9或以下的小牛,您可能需要保留原有的解决方案.