I am trying to do some simple Drag and Drop in Swift similar to the sample code from Apple for Cocoa Drag and Drop. I am not getting far before I have errors.
I have created a swift class dropView with code at bottom. self.registered for types seems like it worked as I get a long list of image types or the shorter list.
When I set the array for registering dragging types to TIF and jpeg types, I get no response for draggingEntered or draggingUpdated. It seems that I am missing something simple? I have the custom view set to the dropView class.
Separately, I get a host of errors when I drag a file (at least for TIF and jpeg) when the array is set to NSImage.imagePasteBoardTypes() see ** at bottom of post.
Why is draggingEntered or draggingUpdated not being called?
Other questions:
Am I registering for dragged types correctly? Is the array in the right format? Is the NSDraggingDestination property bit at the top of the file in the right spot?
import Cocoa
class dropView: NSView, NSDraggingDestination {
init(frame: NSRect) {
super.init(frame: frame)
//let theArray = [NSImage.imagePasteboardTypes()]
let theArray = ["NSTypedFilenamesPboardType:jpg",
"NSTypedFilenamesPboardType:JPG",
"NSTypedFilenamesPboardType:jpeg",
"NSTypedFilenamesPboardType:JPEG",
"NSTypedFilenamesPboardType:jpe",
"NSTypedFilenamesPboardType:TIF"]
registerForDraggedTypes(theArray)
println("INIT and REGISTER")
println(self.registeredDraggedTypes)
}
override func drawRect(dirtyRect: NSRect) {
super.drawRect(dirtyRect)
// Drawing code here.
}
override func draggingEntered(sender: NSDraggingInfo!) -> NSDragOperation {
println("Dragging Entered")
return NSDragOperation.Copy
}
override func draggingUpdated(sender: NSDraggingInfo!) -> NSDragOperation {
println("UPDATED")
return NSDragOperation.Copy
}
}
2014-06-21 11:34:38.728 DragAndDrop[96606:303] -[__NSArrayM length]: unrecognized selector sent to instance 0x610000049d80
2014-06-21 11:34:38.729 DragAndDrop[96606:303] -[__NSArrayM length]: unrecognized selector sent to instance 0x610000049d80
2014-06-21 11:34:38.730 DragAndDrop[96606:303] (
0 CoreFoundation 0x00007fff8ddaf25c __exceptionPreprocess + 172
1 libobjc.A.dylib 0x00007fff83a5de75 objc_exception_throw + 43
2 CoreFoundation 0x00007fff8ddb212d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x00007fff8dd0d322 ___forwarding___ + 1010
4 CoreFoundation 0x00007fff8dd0cea8 _CF_forwarding_prep_0 + 120
5 LaunchServices 0x00007fff8aee1b0a XCFStringHashCaseInsensitive + 111
6 CoreFoundation 0x00007fff8dc6afd8 CFBasicHashFindBucket + 1032
7 CoreFoundation 0x00007fff8dc989c9 CFSetGetValueIfPresent + 121
8 CoreFoundation 0x00007fff8dc9892c -[__NSCFSet member:] + 28
9 CoreFoundation 0x00007fff8dccb008 -[NSSet containsObject:] + 24
10 CoreFoundation 0x00007fff8dd18fcf -[NSSet intersectsSet:] + 735
11 AppKit 0x00007fff86c645ff -[NSView(NSDrag) _hitTest:dragTypes:] + 221
12 AppKit 0x00007fff86c645d2 -[NSView(NSDrag) _hitTest:dragTypes:] + 176
13 AppKit 0x00007fff86c645d2 -[NSView(NSDrag) _hitTest:dragTypes:] + 176
14 AppKit 0x00007fff86c6438c -[NSWindow(NSDrag) _findDragTargetFrom:] + 111
15 AppKit 0x00007fff86c63280 NSCoreDragTrackingProc + 476
16 HIServices 0x00007fff8b8a05a3 DoEnterLeaveHandler + 389
17 HIServices 0x00007fff8b8a2fdd CoreDragMessageHandler + 1741
18 CoreFoundation 0x00007fff8dd5ace8 __CFMessagePortPerform + 760
19 CoreFoundation 0x00007fff8dce08d9 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 41
20 CoreFoundation 0x00007fff8dce084e __CFRunLoopDoSource1 + 478
21 CoreFoundation 0x00007fff8dcd1886 __CFRunLoopRun + 1830
22 CoreFoundation 0x00007fff8dcd0f25 CFRunLoopRunSpecific + 309
23 HIToolbox 0x00007fff8b908a0d RunCurrentEventLoopInMode + 226
24 HIToolbox 0x00007fff8b9087b7 ReceiveNextEventCommon + 479
25 HIToolbox 0x00007fff8b9085bc _BlockUntilNextEventMatchingListInModeWithFilter + 65
26 AppKit 0x00007fff8695726e _DPSNextEvent + 1434
27 AppKit 0x00007fff869568bb -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 122
28 AppKit 0x00007fff8694a9bc -[NSApplication run] + 553
29 AppKit 0x00007fff869357a3 NSApplicationMain + 940
30 DragAndDrop 0x00000001000033fd top_level_code + 109
31 DragAndDrop 0x000000010000343a main + 42
32 libdyld.dylib 0x00007fff8e1925fd start + 1
33 ??? 0x0000000000000003 0x0 + 3
)
2014-06-21 11:34:40.729 DragAndDrop[96606:303] -[__NSArrayM length]: unrecognized selector sent to instance 0x610000049d80
2014-06-21 11:34:40.730 DragAndDrop[96606:303] -[__NSArrayM length]: unrecognized selector sent to instance 0x610000049d80
2014-06-21 11:34:40.731 DragAndDrop[96606:303] (
0 CoreFoundation 0x00007fff8ddaf25c __exceptionPreprocess + 172
1 libobjc.A.dylib 0x00007fff83a5de75 objc_exception_throw + 43
2 CoreFoundation 0x00007fff8ddb212d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x00007fff8dd0d322 ___forwarding___ + 1010
4 CoreFoundation 0x00007fff8dd0cea8 _CF_forwarding_prep_0 + 120
5 LaunchServices 0x00007fff8aee1b0a XCFStringHashCaseInsensitive + 111
6 CoreFoundation 0x00007fff8dc6afd8 CFBasicHashFindBucket + 1032
7 CoreFoundation 0x00007fff8dc989c9 CFSetGetValueIfPresent + 121
8 CoreFoundation 0x00007fff8dc9892c -[__NSCFSet member:] + 28
9 CoreFoundation 0x00007fff8dccb008 -[NSSet containsObject:] + 24
10 CoreFoundation 0x00007fff8dd18fcf -[NSSet intersectsSet:] + 735
11 AppKit 0x00007fff86c645ff -[NSView(NSDrag) _hitTest:dragTypes:] + 221
12 AppKit 0x00007fff86c645d2 -[NSView(NSDrag) _hitTest:dragTypes:] + 176
13 AppKit 0x00007fff86c645d2 -[NSView(NSDrag) _hitTest:dragTypes:] + 176
14 AppKit 0x00007fff86c6438c -[NSWindow(NSDrag) _findDragTargetFrom:] + 111
15 AppKit 0x00007fff86c63280 NSCoreDragTrackingProc + 476
16 HIServices 0x00007fff8b89fca4 DoTrackingMessage + 370
17 HIServices 0x00007fff8b8a2b36 CoreDragMessageHandler + 550
18 CoreFoundation 0x00007fff8dd5ace8 __CFMessagePortPerform + 760
19 CoreFoundation 0x00007fff8dce08d9 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 41
20 CoreFoundation 0x00007fff8dce084e __CFRunLoopDoSource1 + 478
21 CoreFoundation 0x00007fff8dcd1886 __CFRunLoopRun + 1830
22 CoreFoundation 0x00007fff8dcd0f25 CFRunLoopRunSpecific + 309
23 HIToolbox 0x00007fff8b908a0d RunCurrentEventLoopInMode + 226
24 HIToolbox 0x00007fff8b9087b7 ReceiveNextEventCommon + 479
25 HIToolbox 0x00007fff8b9085bc _BlockUntilNextEventMatchingListInModeWithFilter + 65
26 AppKit 0x00007fff8695726e _DPSNextEvent + 1434
27 AppKit 0x00007fff869568bb -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 122
28 AppKit 0x00007fff8694a9bc -[NSApplication run] + 553
29 AppKit 0x00007fff869357a3 NSApplicationMain + 940
30 DragAndDrop 0x00000001000033fd top_level_code + 109
31 DragAndDrop 0x000000010000343a main + 42
32 libdyld.dylib 0x00007fff8e1925fd start + 1
33 ??? 0x0000000000000003 0x0 + 3
)
I am trying to do some simple Drag and Drop in Swift similar to the sample code from Apple for Cocoa Drag and Drop. I am not getting far before I have errors. I have created a swift class dropView with code at bottom. self.registered for types seems like it worked as I get a long list of image types or the shorter list.
For the Drag, SwiftUI has a single method called onDrag (). By adding this modifier to a view, you are doing two important things: you are telling SwiftUI that the view is draggable, and you also set the data that will be attached to the drag operation (in the form of NSItemProvider objects).
Drag and Drop with SwiftUI is very simple. However, if you are completely new to drag and drop on macOS/iOS, the challenge will be to understand NSItemProvider. This is the class that carries the information of the dragged data, and it is a class that has been around for many years.
For example, depending on your app needs, an image can be dragged as an Image, a URL, or raw data. Text can be dragged as simple text, rich text, etc. You may even need to drag your own custom type. Usually, most of the time implementing drag and drop, will be the time spent on that task, and not the UI part of the problem.
(Swift 3, Xcode 8b6, OSX 10.11)
Apple recommends that the older style of pasteboard types should no longer be used and to use UTIs where possible - the better version is
self.register(forDraggedTypes: [kUTTypeURL as String])
This means that you receive drags from the Finder, for all filetypes.
Since NSImage.imagePasteboardTypes
has been deprecated without replacement, you should handle the filtering in draggingEntered:
override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation {
let pasteboard = sender.draggingPasteboard()
let filteringOptions = [NSPasteboardURLReadingContentsConformToTypesKey:NSImage.imageTypes()]
if pasteboard.canReadObject(forClasses: [NSURL.self], options: filteringOptions) {
return NSDragOperation.copy
}
return NSDragOperation() //alternatively: []
}
(credit for the use of NSPasteboardURLReadingContentsConformToTypesKey goes to @TroutDev's tutorial here)
Separately, I get a host of errors when I drag a file (at least for TIF and jpeg) when the array is set to NSImage.imagePasteBoardTypes() see ** at bottom of post.
NSImage.imagePasteboardTypes()
already returns an array, so using it like this:
let theArray = NSImage.imagePasteboardTypes()
instead of like this
let theArray = [NSImage.imagePasteboardTypes()]
will fix the crash.
Why is draggingEntered or draggingUpdated not being called?
If you're dragging from Finder, you probably want let types = [NSFilenamesPboardType]
. The code you have means you have to place data onto the pasteboard yourself -- Finder doesn't put file contents onto the pasteboard, it puts filenames.
Is the NSDraggingDestination property bit at the top of the file in the right spot?
Yep! : NSDraggingDestination
tells Swift that you're about to implement the protocol.
// Public domain
import Cocoa
class DragView: NSView, NSDraggingDestination {
init(frame: NSRect) {
super.init(frame: frame)
let types = [NSFilenamesPboardType]
registerForDraggedTypes(types)
println(self.registeredDraggedTypes)
}
override func drawRect(dirtyRect: NSRect) {
super.drawRect(dirtyRect)
NSColor.whiteColor().set()
NSRectFill(dirtyRect)
}
override func draggingEntered(sender: NSDraggingInfo!) -> NSDragOperation {
println("hello")
return NSDragOperation.Copy
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With