How to support drag and drop in NSView

Issue #410

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import AppKit
import Anchors

class DraggingView: NSView {
var didDrag: ((FileInfo) -> Void)?
let highlightView = NSView()

override init(frame frameRect: NSRect) {
super.init(frame: frameRect)

registerForDraggedTypes([
.fileURL
])

highlightView.isHidden = true
addSubview(highlightView)
activate(highlightView.anchor.edges)
highlightView.wantsLayer = true
highlightView.layer?.borderColor = NSColor(hex: "#FF6CA8").cgColor
highlightView.layer?.borderWidth = 6
}

required init?(coder decoder: NSCoder) {
fatalError()
}

override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation {
highlightView.isHidden = false
return NSDragOperation()
}

override func draggingEnded(_ sender: NSDraggingInfo) {
guard let pathAlias = sender.draggingPasteboard.propertyList(forType: .fileURL) as? String else {
return
}

let url = URL(fileURLWithPath: pathAlias).standardized
let fileInfo = FileInfo(url: url)
didDrag?(fileInfo)
}

override func draggingExited(_ sender: NSDraggingInfo?) {
highlightView.isHidden = true
}

override func draggingUpdated(_ sender: NSDraggingInfo) -> NSDragOperation {
return NSDragOperation()
}
}

To get information about multiple files

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
override func draggingEnded(_ sender: NSDraggingInfo) {
guard let pasteBoardItems = sender.draggingPasteboard.pasteboardItems else {
return
}

let fileInfos: [FileInfo] = pasteBoardItems
.compactMap({
return $0.propertyList(forType: .fileURL) as? String
})
.map({
let url = URL(fileURLWithPath: $0).standardized
return FileInfo(url: url)
})

didDrag(fileInfos)
}

Comments