I have subclassed NSView to receive a dropped folder in order to get its URL. I've been getting the URL to my ViewController class by accessing a property set in my custom NSView class.
import Cocoa
class DropView: NSView {
var droppedURL : URL!
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
// Drawing code here.
}
public required init?(coder: NSCoder) {
super .init(coder: coder)
registerForDraggedTypes([NSPasteboard.PasteboardType.fileURL])
}
public override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation {
return NSDragOperation.copy
}
public override func draggingUpdated(_ sender: NSDraggingInfo) -> NSDragOperation {
NSDragOperation.copy
}
public override func performDragOperation(_ sender: NSDraggingInfo) -> Bool {
let pboard = sender.draggingPasteboard
let urlString = pboard.string(forType: NSPasteboard.PasteboardType.fileURL)
let folderURL = URL(string: urlString!)
print(folderURL)
droppedURL = folderURL
return true
}
}
How can I let my ViewController know when a folder has been dropped onto my NSView and that a URL has been successfully captured? Is there a way other than posting a notification?
Usually you'd use delegates or closures for this. I prefer closures because they're so clean, but it's up to you.
First, define your closure in DropView
:
class DropView: NSView {
var droppedURL : URL!
var droppedSuccessfully: ((URL) -> Void)? /// here!
Then, call it just like how you'd call a function. Make sure to pass in your folderURL
too.
public override func performDragOperation(_ sender: NSDraggingInfo) -> Bool {
let pboard = sender.draggingPasteboard
let urlString = pboard.string(forType: NSPasteboard.PasteboardType.fileURL)
let folderURL = URL(string: urlString!)
print(folderURL)
droppedURL = folderURL
droppedSuccessfully?(folderURL) /// here!
return true
}
Finally, assign the closure back in your ViewController
.
override func viewDidLoad() {
super.viewDidLoad()
...
/// prevent retain cycle
yourDropView.droppedSuccessfully = { [weak self] url in
print("URL received: \(url)")
}
}