在Swift中拖放 - 注册拖动类型的问题?

Chr*_*ris 7 drag-and-drop swift

背景

我试图在Swift中做一些简单的拖放,类似于Apple for Cocoa Drag and Drop的示例代码.在我遇到错误之前我没有走远.

我已经创建了一个swift类dropView,底部带有代码.对于类型的self.registered看起来像是工作,因为我得到了很长的图像类型列表或较短的列表.

当我设置数组以将拖动类型注册到TIF和jpeg类型时,我没有得到draggingEntered或draggingUpdated的响应.看来我错过了一些简单的东西?我将自定义视图设置为dropView类.

另外,当我将数组设置为NSImage.imagePasteBoardTypes()时,拖动文件(至少对于TIF和jpeg)时会出现大量错误.请参阅帖子底部的**.

问题

为什么不调用draggingEntered或draggingUpdated?

其他问题:

我正确注册拖动类型吗?阵列格式是否正确?NSDraggingDestination属性位于文件顶部的正确位置吗?

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
}

}
Run Code Online (Sandbox Code Playgroud)

**NSImage.imagePasteBoardTypes()时的错误

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
)
Run Code Online (Sandbox Code Playgroud)

hao*_*hao 6

关于崩溃

另外,当我将数组设置为NSImage.imagePasteBoardTypes()时,拖动文件(至少对于TIF和jpeg)时会出现大量错误.请参阅帖子底部的**.

NSImage.imagePasteboardTypes() 已经返回一个数组,所以像这样使用它:

let theArray = NSImage.imagePasteboardTypes()
Run Code Online (Sandbox Code Playgroud)

而不是像这样

let theArray = [NSImage.imagePasteboardTypes()]
Run Code Online (Sandbox Code Playgroud)

将解决崩溃.

关于NSDragDestination

为什么不调用draggingEntered或draggingUpdated?

如果你是从Finder拖动,你可能想要let types = [NSFilenamesPboardType].你拥有的代码意味着你必须自己将数据放到粘贴板上 - Finder不会将文件内容放到粘贴板上,它会放置文件名.

NSDraggingDestination属性位于文件顶部的正确位置吗?

是的!: NSDraggingDestination告诉Swift您即将实施该协议.

工作实例

// 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
    }
}
Run Code Online (Sandbox Code Playgroud)


gre*_*ght 6

(Swift 3,Xcode 8b6,OSX 10.11)

Apple建议不再使用旧式的粘贴板类型,并尽可能使用UTI - 更好的版本

self.register(forDraggedTypes: [kUTTypeURL as String])
Run Code Online (Sandbox Code Playgroud)

这意味着您可以从Finder接收所有文件类型的拖动.

由于NSImage.imagePasteboardTypes已经弃用而没有替换,您应该在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: []
}
Run Code Online (Sandbox Code Playgroud)

(使用NSPasteboardURLReadingContentsConformToTypesKey的信用请转到@TroutDev的教程)