I recently started using Swift to build OS X apps and I am wondering how I could implement a drag-and-drop zone.
More specifically, I built an app that processes ima
Here's an example I'm using in an application.
NSDraggingDestination to your subclass declaration if necessary (not needed for NSImageView because it already conforms to the protocol)NSFilenamesPboardType)registerForDraggedTypesdraggingEntered, draggingUpdated and performDragOperationNSDragOperation from these methodsdraggingPasteboard arrayIn my example I've added a function to check if the file extension is amongst the ones we want.
Swift 2
class MyImageView: NSImageView {
override func drawRect(dirtyRect: NSRect) {
super.drawRect(dirtyRect)
}
required init?(coder: NSCoder) {
super.init(coder: coder)
// Declare and register an array of accepted types
registerForDraggedTypes([NSFilenamesPboardType, NSURLPboardType, NSPasteboardTypeTIFF])
}
let fileTypes = ["jpg", "jpeg", "bmp", "png", "gif"]
var fileTypeIsOk = false
var droppedFilePath: String?
override func draggingEntered(sender: NSDraggingInfo) -> NSDragOperation {
if checkExtension(sender) {
fileTypeIsOk = true
return .Copy
} else {
fileTypeIsOk = false
return .None
}
}
override func draggingUpdated(sender: NSDraggingInfo) -> NSDragOperation {
if fileTypeIsOk {
return .Copy
} else {
return .None
}
}
override func performDragOperation(sender: NSDraggingInfo) -> Bool {
if let board = sender.draggingPasteboard().propertyListForType("NSFilenamesPboardType") as? NSArray,
imagePath = board[0] as? String {
// THIS IS WERE YOU GET THE PATH FOR THE DROPPED FILE
droppedFilePath = imagePath
return true
}
return false
}
func checkExtension(drag: NSDraggingInfo) -> Bool {
if let board = drag.draggingPasteboard().propertyListForType("NSFilenamesPboardType") as? NSArray,
path = board[0] as? String {
let url = NSURL(fileURLWithPath: path)
if let fileExtension = url.pathExtension?.lowercaseString {
return fileTypes.contains(fileExtension)
}
}
return false
}
}
Swift 3
class MyImageView: NSImageView {
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
}
required init?(coder: NSCoder) {
super.init(coder: coder)
// Declare and register an array of accepted types
register(forDraggedTypes: [NSFilenamesPboardType, NSURLPboardType, NSPasteboardTypeTIFF])
}
let fileTypes = ["jpg", "jpeg", "bmp", "png", "gif"]
var fileTypeIsOk = false
var droppedFilePath: String?
override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation {
if checkExtension(drag: sender) {
fileTypeIsOk = true
return .copy
} else {
fileTypeIsOk = false
return []
}
}
override func draggingUpdated(_ sender: NSDraggingInfo) -> NSDragOperation {
if fileTypeIsOk {
return .copy
} else {
return []
}
}
override func performDragOperation(_ sender: NSDraggingInfo) -> Bool {
if let board = sender.draggingPasteboard().propertyList(forType: "NSFilenamesPboardType") as? NSArray,
imagePath = board[0] as? String {
// THIS IS WERE YOU GET THE PATH FOR THE DROPPED FILE
droppedFilePath = imagePath
return true
}
return false
}
func checkExtension(drag: NSDraggingInfo) -> Bool {
if let board = drag.draggingPasteboard().propertyList(forType: "NSFilenamesPboardType") as? NSArray,
path = board[0] as? String {
let url = NSURL(fileURLWithPath: path)
if let fileExtension = url.pathExtension?.lowercased() {
return fileTypes.contains(fileExtension)
}
}
return false
}
}