【问题标题】:Difficulty with Drag and Drop拖放困难
【发布时间】:2021-08-28 21:47:10
【问题描述】:

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

使用下面显示的代码,当我将对象拖到 TextField 控件上时,我的 print("dragging entered") 行会触发,但是当我释放它时,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
    }
    
}

【问题讨论】:

  • 仅在您喜欢的情况下说明您要达到的目标。
  • 我希望能够将文件或目录拖到 TextField 上并显示它的 url(以及将该 url 用于进一步处理 url 目录中的一个或多个项目。)
  • 那你为什么要对NSTextField进行子分类呢?你应该继承NSView。将其放在您的文本字段下方。
  • 我敢肯定我尝试这样做的原因是因为我对它的工作原理缺乏了解。我想如果我想为控件提供拖放功能,我需要子类化,然后将该功能构建到我的版本中。 (另外,即使这样做是错误的,为什么它不起作用?)感谢您的帮助和建议。
  • 哦,我想尝试这样做的另一个原因是我的窗口中有多个 TextField,并且我需要每个 TextField 代表一个不同的目录。

标签: swift macos


【解决方案1】:

将此自定义类分配给情节提要上的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)")
        }
    }
}

【讨论】:

    猜你喜欢
    • 2014-08-07
    • 1970-01-01
    • 2013-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-07
    • 2016-12-24
    • 2019-07-16
    相关资源
    最近更新 更多