您知道当您从 Dock 中拖出一个项目并出现云拖动光标时的效果,当您放手时它会以噗噗的效果消失吗?同样,在 Xcode 中,当您将断点拖到行号间距之外时,也会发生同样的情况。
我想在我的应用程序中实现相同的效果,但找不到正确的方法。
我有一个 NSImageView 后代来实现 NSDraggingSource 和 NSDraggingDestination 协议。我有这个视图的几个实例,它们允许在其他视图之间拖动它们的内容(在这种情况下会发生复制操作,但这仅与显示我已实现拖放并完全适用于标准任务有关)。
现在,当我将图像从其视图拖到任何地方(另一个视图实例除外)时,我希望删除操作在放置时进行。然而,拖动操作完全由目标视图控制。我可以设法让他们按照我想要的方式做出响应(尽管这将是很多工作),但如果我拖到我的应用程序之外,它会完全失败。
如果我可以获得删除拖动操作,我可以通过以下方式轻松处理这个问题:
- (void)draggedImage: (NSImage *)image
endedAt: (NSPoint)screenPoint
operation: (NSDragOperation)operation
{
if (operation == NSDragOperationDelete) {
NSRect rect = [self.window convertRectToScreen: [self convertRect: self.frame fromView: nil]];
NSShowAnimationEffect(NSAnimationEffectPoof, rect.origin, self.bounds.size, nil, nil, NULL);
}
}
我已经尝试像这样设置删除光标:
- (void)draggingSession: (NSDraggingSession *)session
movedToPoint: (NSPoint)screenPoint
{
if (!NSPointInRect(screenPoint, self.window.frame)) {
[[NSCursor disappearingItemCursor] set];
}
}
(为简单起见,这是目前整个windw)。只要我不点击桌面或查找器窗口,它就可以工作。In 开始闪烁,可能是因为 Finder 同时设置了自己的拖动光标。当我到达码头时,它完全没有效果。当我定义自己的粘贴板数据类型时也会发生这种情况。
此外,我的应用程序中的任何其他启用拖放的视图仍将接受我不希望发生的拖动数据(例如 NSTextView)(我正在使用自定义方案将 NSURL 写入拖动粘贴板)。
更新:
我又走了几步。正如彼得已经指出的那样,必须处理draggingSession:sourceOperationmaskForDraggingContext:
在我的代码中看起来如此的内容:
- (NSDragOperation) draggingSession: (NSDraggingSession *)session
sourceOperationMaskForDraggingContext: (NSDraggingContext)context;
{
switch(context) {
case NSDraggingContextOutsideApplication:
return NSDragOperationDelete;
break;
case NSDraggingContextWithinApplication:
default:
return NSDragOperationDelete | NSDragOperationMove;
break;
}
}
这解决了 2 个问题:1)在应用程序外部根本不接受拖动操作,2)它使所有标准视图也无法接受此操作(因为 NSOutlineView、NSTextView 等不处理给定的拖动操作)。此外,我创建了自己的粘贴板数据类型,但这似乎没有必要。拥有自己的仍然更清楚。
不幸的是,放在我的 NSImageView 后代之外(在应用程序内部和外部)并没有给我 NSDragOperationDelete in draggedImage:endedAt:operation:
(我在上面指定的),而是 NSDragOperationNone。此外,将鼠标移到应用程序外时的拖动光标是不允许的,而不是消失的项目。所以,如果有人能解决这两件事,我会接受它作为我问题的答案。