2011-04-14 5 views
14

사용자가 Finder에서 파일을 드래그하여 NSStatusItem에 놓을 수있는 응용 프로그램을 작성하려고합니다. 지금까지 끌어서 놓기 인터페이스를 구현하는 사용자 지정보기를 만들었습니다. 이 뷰를 NSWindow의 하위 뷰로 추가하면 마우스 커서가 적절한 피드백을주고, 내 코드를 삭제하면 코드가 실행됩니다.NSStatusItem으로 끌어서 놓기

그러나 NSStatusItem's보기와 동일한보기를 사용하면 올바르게 동작하지 않습니다. 마우스 커서는 파일을 삭제할 수 있음을 나타내는 적절한 피드백을 제공하지만 파일을 놓을 때 드롭 코드가 실행되지 않습니다.

NSStatusItem으로 드래그 앤 드롭을 사용하려면 어떻게해야합니까?

답변

30

필자는 마침내 이것을 테스트 해 보았습니다. 완벽하게 작동하므로 코드에 문제가 있습니다. 하지만

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

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

굉장! 하지만이보기 및 쇼 메뉴를 어떻게 처리 할 수 ​​있습니까? – Oleg

+0

@Oleg는 클릭 처리를 구현하고이보기에 메뉴를 표시 할 수 있었습니까? –

+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

11

요세미티 때문에, NSStatusItem에보기를 설정하는 방법은 사용되지 않습니다 :

여기
@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에 새로운 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 매버릭스 이하를 지원하는 경우 기존 솔루션을 계속해야 할 수도 있습니다 만 사용할 수 있음을 유의하시기 바랍니다.

+0

대단히 감사합니다. 어떤 이유로, 도크의 "다운로드"스택에서 파일을 드래그 할 때 작동하지 않습니다 (Finder에서 올바르게 작동 함). 왜 그런 일이 일어날 지 모릅니다. –

+0

@CoffeeBite이 레이더에보고 된 것과 같은 문제가 있습니다 : http://openradar.appspot.com/radar?id=1745403. 결국이 문제를 해결할 방법을 찾았습니까? – Pim

+0

@Pim 예.'performDragOperation'은 호출되지 않지만'draggingEnded'는 호출됩니다. 그래서 드래그가 상태 메뉴 항목의 프레임 내에서 끝났는지 확인합니다. ''' FUNC의 draggingEnded (보낸 사람 : NSDraggingInfo)! { 보낸 경우 = 전무 { NSPointInRect (! 보낸 사람 .draggingLocation(), statusItem.button.frame) { 판지 할 경우 경우 : NSPasteboard = 보낸 사람을! draggingPasteboard() { // 클립 보드 데이터에서 파일을 가져 와서 처리합니다. } } } } ''' –