macOS拖放行为NSDraggingDestination
macOS拖放行为NSDraggingDestination

macOS拖放行为NSDraggingDestination

NSDraggingDestination 是 macOS AppKit 框架中的协议,用于实现拖放目标(拖入)行为。

如果希望视图、窗口或控件能够作为 拖拽目标,例如接收文件、图片、文本、自定义数据。

就要让该对象(通常是 NSView 或 NSWindow)实现 NSDraggingDestination 协议。

基本功能

当用户拖动某个项目(如文件、图片、文本)到mac应用上时,系统会:

1、向视图发送 NSDraggingDestination 协议方法

2、可以根据拖入类型决定:

是否接受。

拖入时显示什么反馈(边框高亮等)。

拖放到哪里触发什么操作。

常用方法

1、draggingEntered(_:):拖入区域时触发,可返回接受类型(如 .copy)。

2、draggingUpdated(_:):拖动过程中不断触发,用于动态反馈。

3、draggingExited(_:):拖出区域时触发。

4、prepareForDragOperation(_:):放开前准备,返回是否接受。

5、performDragOperation(_:):实际执行放入动作。

6、concludeDragOperation(_:):拖拽完成后调用(动画完成)。

使用场景

1、通过draggingEntered返回 .copy 让系统显示绿色加号光标。

也可以在NSView中设置:

override func draw(_ dirtyRect: NSRect) {
    if isHighlighting {
        NSColor.selectedControlColor.set()
        __NSRectFillUsingOperation(dirtyRect, .sourceOver)
    }
}

2、拖入图片到视图中

registerForDraggedTypes([.tiff])

func performDragOperation(_ sender: NSDraggingInfo) -> Bool {
    if let data = sender.draggingPasteboard.data(forType: .tiff),
       let image = NSImage(data: data) {
        self.image = image
        self.needsDisplay = true
        return true
    }
    return false
}

3、让视图实现协议

class DropReceivingView: NSView, NSDraggingDestination {
    override func awakeFromNib() {
        super.awakeFromNib()

        registerForDraggedTypes([.fileURL, .string])
    }

    func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation {
        return .copy
    }

    func performDragOperation(_ sender: NSDraggingInfo) -> Bool {
        let pasteboard = sender.draggingPasteboard

        if let urls = pasteboard.readObjects(forClasses: [NSURL.self], options: nil) as? [URL] {
            for url in urls {
                print("拖入文件:\(url.path)")
            }
            return true
        }

        return false
    }
}

4、注册支持的类型

registerForDraggedTypes([
    .fileURL,         // 拖入文件
    .string,          // 拖入纯文本
    .tiff,            // 拖入图片
    NSPasteboard.PasteboardType("public.jpeg") // 支持其他 UTI
])

总结

当需要实现拖入文件、图片等数据到窗口时,可以使用NSDraggingDestination,如果是App内部控件之间的拖动,需要使用NSDraggingSource。

SwiftUI没有原生完整拖动支持,在macOS13之前的版本,可以使用NSViewRepresentable包装NSView + NSDraggingDestination。

通常配合辅助类型NSPasteboard、NSDraggingInfo(拖拽上下文)和NSDragOperation(拖入操作类型 .copy,.link,.move)使用。

   

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开发者。

欢迎加入我们的 微信交流群QQ交流群,交流更多精彩内容!
微信交流群二维码 QQ交流群二维码

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注