2011-04-14 53 views
14

我正在嘗試編寫一個應用程序,允許用戶從Finder中拖動文件並將其放到NSStatusItem上。到目前爲止,我創建了一個實現拖放界面的自定義視圖。當我將這個視圖作爲NSWindow的子視圖添加時,它全部正常工作 - 鼠標光標提供了適當的反饋,並且在我的代碼被刪除時執行。使用NSStatusItem拖放

但是,當我使用與NSStatusItem's視圖相同的視圖時,它的行爲不正確。鼠標光標提供了適當的反饋,指出文件可以被刪除,但是當我刪除文件時,我的drop代碼永遠不會被執行。

有沒有什麼特別的我需要做的,以使拖放與NSStatusItem

回答

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 

這裏是你如何創建的狀態項:

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

DragStatusView* dragView = [[DragStatusView alloc] initWithFrame:NSMakeRect(0, 0, 24, 24)]; 
[item setView:dragView]; 
[dragView release]; 
+3

太棒了!但我如何處理點擊這個視圖並顯示菜單? – Oleg 2012-06-20 11:14:57

+0

@Oleg是否能夠實現點擊處理並在此視圖上顯示菜單? – 2013-02-05 10:10:21

+1

我添加按鈕。然後添加DragStatusView作爲子視圖。 \t'_titleButton = [[NSButton alloc] initWithFrame:NSMakeRect(0,-2,26,24)]; \t [_titleButton setBordered:NO]; \t [_titleButton setButtonType:NSMomentaryChangeButton]; \t [_titleButton setImagePosition:NSImageOnly]; \t [_titleButton setBezelStyle:NSThickerSquareBezelStyle]; \t [_titleButton setTarget:self]; \t \t \t \t [_titleButton setImage:[NSImage imageNamed:@「IconDefault.png」]]; \t \t [_titleButton setAction:@selector(showMenu :)];; \t \t \t self.view = [[ILDragStatusView alloc] initWithFrame:NSMakeRect(0,1,26,24)]; \t [self.view addSubview:_titleButton];' – Oleg 2013-02-06 11:58:48

11

由於優勝美地,對NSStatusItem設置視圖的方法已經過時,但好在有使用上NSStatusItemNSStatusItemButton財產好得多方式:

- (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小牛或以下。

+0

非常感謝。出於某種原因,當我將該文件從擴展塢的「Downloads」堆棧(從Finder中正常工作)拖出時,這不起作用。任何想法爲什麼這可能會發生? – 2015-05-07 02:14:21

+0

@CoffeeBite我遇到了同樣的問題,正如本報告中所報道的那樣:http://openradar.appspot.com/radar?id = 1745403。你最終找到了解決這個問題的方法嗎? – Pim 2017-12-18 14:48:19

+0

@Pim是的。'performDragOperation'不被調用,但是'draggingEnded'是。所以我檢查拖動是否在狀態菜單項的框架內結束。 ''' FUNC draggingEnded(發件人:NSDraggingInfo)!{ 如果發件人=零{ 如果NSPointInRect(發件人.draggingLocation(),statusItem.button.frame!){ 如果讓紙板:NSPasteboard =發送者! draggingPasteboard(){ //從剪貼板數據獲取文件並做些事情。 } } } } ''' – 2017-12-18 20:57:02