首页 > 解决方案 > 拖放困难

问题描述

我很难理解如何在 macOS 应用程序中实现简单的拖放。我想要做的是制作一个 TextField ,它可以接受拖放到它上面的目录或文件并捕获该目录或文件的 URL。

使用下面显示的代码,print("dragging entered")当我将对象拖到 TextField 控件上时,我的行会触发,但是当我释放它时performDragOperation不会触发。

谁能帮我理解简单的拖放?

谢谢

进口可可

class DropTextField: NSTextField {

    var dragTypes : [NSPasteboard.PasteboardType] = [.fileURL, .URL]

    override func draw(_ dirtyRect: NSRect) {
        super.draw(dirtyRect)

        // Drawing code here.
    }
    
    override func awakeFromNib() {
        self.registerForDraggedTypes(dragTypes)
    }
    
    public override func prepareForDragOperation(_ sender: NSDraggingInfo) -> Bool {
        return true
    }
    
    public override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation {
        print("dragging engtered")
        return NSDragOperation.copy
    }
    
    
    public override func performDragOperation(_ sender: NSDraggingInfo) -> Bool {
        print("drag operation")
        return true
    }
    
}

标签: swiftmacos

解决方案


将此自定义类分配给NSTextField情节提要上的对象并在控制器中创建一个插座:

public class DragTextField: NSTextField {
    
    public var completionHandler: (URL) -> Void = { fileURL in Swift.print(fileURL) }
    
    public override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation { return NSDragOperation.copy }
    public override func draggingUpdated(_ sender: NSDraggingInfo) -> NSDragOperation { return NSDragOperation.copy }
    public override func performDragOperation(_ sender: NSDraggingInfo) -> Bool {
        let pboard = sender.draggingPasteboard
        
        if let fileURLFromClipboard = pboard.string(forType: NSPasteboard.PasteboardType.fileURL) {
            
            let sourceFileURL = URL(string: fileURLFromClipboard)!
            print(sourceFileURL)
            completionHandler(sourceFileURL)
        }
        return true
    }
    
    public required init?(coder: NSCoder) {
        super.init(coder: coder)
        
        stringValue = "Drop File Here";
        isEditable = false
        wantsLayer = true;
        layer?.backgroundColor = NSColor.blue.cgColor
        
        // Register for file name drag
        registerForDraggedTypes([NSPasteboard.PasteboardType.fileURL])
    }
}

用法:

class ViewController: NSViewController {
    
    @IBOutlet weak var dropView: DragTextField!

    override func viewDidLoad() {
        super.viewDidLoad()
        dropView.completionHandler = {
            print("File Path:  \($0)")
        }
    }
}

推荐阅读