Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 如何将NSStatusItem用作拖动目标?_Objective C_Macos_Cocoa_Drag And Drop_Nsdragginginfo - Fatal编程技术网

Objective c 如何将NSStatusItem用作拖动目标?

Objective c 如何将NSStatusItem用作拖动目标?,objective-c,macos,cocoa,drag-and-drop,nsdragginginfo,Objective C,Macos,Cocoa,Drag And Drop,Nsdragginginfo,我正在尝试构建一个应用程序,允许用户将文件从Finder拖到菜单栏图标进行处理。我在旅途中取得了进步,但我似乎无法登上这座山。我尝试将NSView子类化并实现拖动消息 @interface CMDroppableView : NSView <NSMenuDelegate> 拖动消息: -(NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender{ NSLog(@"Drag Enter"); r

我正在尝试构建一个应用程序,允许用户将文件从Finder拖到菜单栏图标进行处理。我在旅途中取得了进步,但我似乎无法登上这座山。我尝试将NSView子类化并实现拖动消息

@interface CMDroppableView : NSView <NSMenuDelegate>
拖动消息:

-(NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender{
    NSLog(@"Drag Enter");
    return NSDragOperationCopy;
}

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

-(void)draggingExited:(id <NSDraggingInfo>)sender{
    NSLog(@"Drag Exit");
}

-(BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender{
     return YES;
}

-(BOOL)performDragOperation:(id <NSDraggingInfo>)sender{
    return YES;
}
还是没什么。那么我哪里出了问题


谢谢

Edit:D'oh,您正在
-awakeFromNib
中注册拖动类型,如果没有从nib加载视图,将不会调用该类型。尝试在
-initWithFrame:
中注册拖动类型

旧答案: IIRC您不需要在状态项上设置菜单。我要做的是让我的自定义视图管理菜单,并执行以下操作:

- (void)setMenu:(NSMenu *)menu {
    [menu setDelegate:self];
    [super setMenu:menu];
}

- (void)mouseDown:(NSEvent *)event {
    [statusItem popUpStatusItemMenu:[self menu]]; // or another method that returns a menu
}

- (void)menuWillOpen:(NSMenu *)menu {
    highlight = YES;
    [self setNeedsDisplay:YES];
}

- (void)menuDidClose:(NSMenu *)menu {
    highlight = NO;
    [self setNeedsDisplay:YES];
}

- (void)drawRect:(NSRect)rect {
    NSImage *img = highlight ? [alternateImage copy] : [image copy];
    NSRect bounds = [self bounds];
    [statusItem drawStatusBarBackgroundInRect:bounds withHighlight:highlight];
    
    // rest of drawing code goes here, including drawing img where appropriate
}

在自定义视图的实现中。这确保了菜单行为与默认行为相同。

通过反复试验,我偶然发现了解决方案。我在awakeFromNib消息中注册了可接受的拖动类型(如原始问题所示)。但是,我没有使用IB来设置此视图,因此从未调用此方法。将注册码移动到initFromFrame消息似乎解决了这个问题

- (id)initWithFrame:(NSRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        ...
        [self registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType]];
    }
    return self;
}

您是否实现了Draggingered:和performDragOperation:方法?是的,我实现了。我会更新我的问题,将它们包括在内。我怀疑你只是无法做到这一点。将对象拖动到菜单不是正常的UI行为,我认为
NSStatusItem
视图可能具有系统级的交互限制。“如果视图对鼠标按下/按下以外的任何东西做出响应,我都会感到惊讶。”罗布,这很有趣。那么,像CloudApp这样的应用程序如何使您能够将文件放到状态栏图标上?@Wevah,请您回答这个问题好吗?我正在将NSMenu设置为我的自定义视图,而不是NSStatusItem。更重要的是,你如何处理你的拖拽目的地?哦,糟糕。我会更新我的答案。不过,目前睡眠不足……哎呀,在编辑我的答案之前,我没有读过这个自我回答。你应该接受你的是正确的!(投票赞成。)
- (void)setMenu:(NSMenu *)menu {
    [menu setDelegate:self];
    [super setMenu:menu];
}

- (void)mouseDown:(NSEvent *)event {
    [statusItem popUpStatusItemMenu:[self menu]]; // or another method that returns a menu
}

- (void)menuWillOpen:(NSMenu *)menu {
    highlight = YES;
    [self setNeedsDisplay:YES];
}

- (void)menuDidClose:(NSMenu *)menu {
    highlight = NO;
    [self setNeedsDisplay:YES];
}

- (void)drawRect:(NSRect)rect {
    NSImage *img = highlight ? [alternateImage copy] : [image copy];
    NSRect bounds = [self bounds];
    [statusItem drawStatusBarBackgroundInRect:bounds withHighlight:highlight];
    
    // rest of drawing code goes here, including drawing img where appropriate
}
- (id)initWithFrame:(NSRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        ...
        [self registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType]];
    }
    return self;
}