Objective c 如何将NSStatusItem用作拖动目标?
我正在尝试构建一个应用程序,允许用户将文件从Finder拖到菜单栏图标进行处理。我在旅途中取得了进步,但我似乎无法登上这座山。我尝试将NSView子类化并实现拖动消息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
@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;
}