This works for a child object of NSWindow, probably also for child's of NSView, but I have not tested that.
In awakeFromNib:
override func awakeFromNib() {
// ... other stuff here
// Add drag and drop support
registerForDraggedTypes([NSFilenamesPboardType])
}
Then add the following operations to the NSWindow child:
// MARK: - NSDraggingDestination protocol
func draggingEntered(sender: NSDraggingInfo) -> NSDragOperation {
let sourceDragMask = sender.draggingSourceOperationMask()
let pboard = sender.draggingPasteboard()!
if pboard.availableTypeFromArray([NSFilenamesPboardType]) == NSFilenamesPboardType {
if sourceDragMask.rawValue & NSDragOperation.Generic.rawValue != 0 {
return NSDragOperation.Generic
}
}
return NSDragOperation.None
}
func performDragOperation(sender: NSDraggingInfo) -> Bool {
// Get the pasteboard
if let pboard = sender.draggingPasteboard() {
// Get the Y coordinate for the drop
let dropCoordinate = sender.draggingLocation()
// Since our frame is bigger than the scrollview frame, check if the drop position is within any of our scrollviews. If it is not inside a scrollview, then exit now
if !coordinateIsInAChildView(dropCoordinate) { return false }
// Offset the Y coordinate for the scrollview origin
let dropPoint = myView.convertPoint(dropCoordinate, toView: myScrollView.contentView)
// Get the index for the drop
let dropIndex = (myScrollView.documentView as! MyView).lineIndexFromYCoordinate(dropPoint.y)
// Make sure that there are filenames in the pasteboard
if pboard.availableTypeFromArray([NSFilenamesPboardType]) == NSFilenamesPboardType {
// Get the filenames from the pasteboard
let files = filesFromPboard(pboard)
// Add the filenames to the datasource
insertLines(files, atIndex: dropIndex)
// Update the view
myView.needsDisplay = true
// The drop was accepted
return true
}
}
// Still here, then something went wrong. The drop is not accepted.
return false
}
Discussion:
NSWindows already implements the NSDraggingDestination protocol. So we only have to implement those operations that we want. I have not implemented the "draggingUpdated" and "prepareForDragOperation" operations as the default behaviour is exactly what is needed.
It is probably obvious, but you have to implement some stuff yourself. For example I have to check if the drop location is in a childview, and I have to find out what the Y coordinate for the drop is. You will have to remove/replace that.
Do note that the dragging operations may not be marked 'private'.
Happy coding
2015-06-17: Added more pboard and drag & drop stuff in this post
Did this help?, then please help out a small independent.
If you decide that you want to make a small donation, you can do so by clicking this
link: a cup of coffee ($2) or use the popup on the right hand side for different amounts.
Payments will be processed by PayPal, receiver will be sales at balancingrock dot nl
Bitcoins will be gladly accepted at: 1GacSREBxPy1yskLMc9de2nofNv2SNdwqH
We don't get the world we wish for... we get the world we pay for.
No comments:
Post a Comment