【问题标题】:Drag and Drop with NSStatusItem使用 NSStatusItem 拖放
【发布时间】:2011-08-05 13:17:12
【问题描述】:

我正在尝试编写一个应用程序,该应用程序允许用户将文件从 Finder 拖放到NSStatusItem 上。到目前为止,我已经创建了一个实现拖放界面的自定义视图。当我将此视图添加为 NSWindow 的子视图时,它一切正常——鼠标光标提供适当的反馈,并且当我放下时,我的代码被执行。

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

我需要做一些特别的事情来启用NSStatusItem 的拖放功能吗?

【问题讨论】:

    标签: cocoa drag-and-drop nsstatusitem


    【解决方案1】:

    我终于开始测试它并且它运行良好,所以你的代码肯定有问题。

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

    @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
    

    创建状态项的方法如下:

    NSStatusItem* item = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength] retain];
    
    DragStatusView* dragView = [[DragStatusView alloc] initWithFrame:NSMakeRect(0, 0, 24, 24)];
    [item setView:dragView];
    [dragView release];
    

    【讨论】:

    • 太棒了!但是我如何处理点击这个视图和显示菜单呢?
    • @Oleg 你能在这个视图上实现点击处理和显示菜单吗?
    • 我添加按钮。然后将 DragStatusView 添加为子视图。 _titleButton = [[NSButton alloc] initWithFrame:NSMakeRect(0, -2, 26, 24)]; [_titleButton setBordered:NO]; [_titleButton setButtonType:NSMomentaryChangeButton]; [_titleButton setImagePosition:NSImageOnly]; [_titleButton setBezelStyle:NSThickerSquareBezelStyle]; [_titleButton setTarget:self]; [_titleButton setImage:[NSImage imageNamed:@"IconDefault.png"]]; [_titleButton setAction:@selector(showMenu:)]; self.view = [[ILDragStatusView alloc] initWithFrame:NSMakeRect(0, 1, 26, 24)]; [self.view addSubview:_titleButton];
    【解决方案2】:

    从优胜美地开始,在NSStatusItem 上设置视图的方法已被弃用,但幸运的是,有一种更好的方法可以使用NSStatusItem 上的新NSStatusItemButton 属性:

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

    }

    - (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender {
        return NSDragOperationCopy;
    }
    
    - (BOOL)performDragOperation:(id<NSDraggingInfo>)sender {
      //drag handling logic
    }
    

    请注意,button 属性仅从 10.10 开始可用,如果您支持 10.9 Mavericks 或更低版本,您可能必须保留旧解决方案。

    【讨论】:

    • 非常感谢。出于某种原因,当我从扩展坞的“下载”堆栈中拖动文件时,这不起作用(在 Finder 中工作正常)。知道为什么会发生这种情况吗?
    • @CoffeeBite 我遇到了同样的问题,正如雷达中所报告的那样:openradar.appspot.com/radar?id=1745403。你最终找到解决这个问题的方法了吗?
    • @Pim 是的。 performDragOperation 未被调用,但 draggingEnded 被调用。所以我检查拖动是否在状态菜单项的框架内结束。 ``` func draggingEnded(sender: NSDraggingInfo?) { if sender != nil { if NSPointInRect(sender!.draggingLocation(), statusItem.button.frame) { if let pasteboard: NSPasteboard = sender!.draggingPasteboard() { //从剪贴板数据中获取文件并做一些事情。 } } } } ```
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-25
    • 1970-01-01
    • 2020-06-01
    • 1970-01-01
    • 2012-07-12
    • 1970-01-01
    相关资源
    最近更新 更多