在NSTokenField中掉落token



我正在实现一个应用程序,从NSTableView行可以拖放到NSTokenField中,但我正在努力实现交互的下拉端。我子类化了NSTokenField(如下面的调试代码所示)。但是我只看到对draggingEntered:updateDraggingItemsForDrag:方法的调用。即使我返回一个有效的NSDragOperation (Copy),也没有调用NSDraggingDestination中的其他方法。光标移动到令牌字段时短暂地闪烁到复制图标,但随后返回到正常光标。

为了调试的目的,我尝试实现与NSDraggingDestination相关的所有方法,如下面的代码所示。是否有其他类或NSTokenField的一部分是处理掉落?有可能推翻它吗?

我已经确认,粘贴板确实有有效的粘贴板类型的数据。

let kPasteboardType = "SamplePasteboardType"
class MyTokenField : NSTokenField
{
    override func draggingEntered(sender: NSDraggingInfo) -> NSDragOperation {
        // entered
        NSLog("ENTERED")
        // must come from same window
        guard self.window == sender.draggingDestinationWindow() else {
            return super.draggingEntered(sender)
        }

        // has valid pasteboard data?
        let pb = sender.draggingPasteboard()
        if let _ = pb.dataForType(kPasteboardType) {
            NSLog("MATCHED")
            return NSDragOperation.Copy
        }
        return super.draggingEntered(sender)
    }
    override func draggingUpdated(sender: NSDraggingInfo) -> NSDragOperation {
        NSLog("UPDATED")
        // must come from same window
        guard self.window == sender.draggingDestinationWindow() else {
            return super.draggingUpdated(sender)
        }
        // has valid pasteboard data?
        let pb = sender.draggingPasteboard()
        if let _ = pb.dataForType(kPasteboardType) {
            return NSDragOperation.Copy
        }
        return super.draggingUpdated(sender)
    }
    override func draggingExited(sender: NSDraggingInfo?) {
        NSLog("EXITED")
        super.draggingExited(sender)
    }
    override func prepareForDragOperation(sender: NSDraggingInfo) -> Bool {
        NSLog("PREPARE")
        return super.prepareForDragOperation(sender)
    }
    override func performDragOperation(sender: NSDraggingInfo) -> Bool {
        NSLog("PERFORM")
        return super.performDragOperation(sender)
    }
    override func concludeDragOperation(sender: NSDraggingInfo?) {
        NSLog("CONCLUDE")
        super.concludeDragOperation(sender)
    }
    override func draggingEnded(sender: NSDraggingInfo?) {
        NSLog("ENDED")
        super.draggingEnded(sender)
    }
    override func updateDraggingItemsForDrag(sender: NSDraggingInfo?) {
        // super.updateDraggingItemsForDrag(sender)
        guard let drag = sender else {
            return
        }
        let classes: [AnyClass] = [NSPasteboardItem.self]
        let options: [String: AnyObject] = [NSPasteboardURLReadingContentsConformToTypesKey: [kPasteboardType]]
        drag.enumerateDraggingItemsWithOptions(NSDraggingItemEnumerationOptions.ClearNonenumeratedImages, forView: self, classes: classes, searchOptions: options) {
            (item, idx, stop) in
            NSLog("(item)")
        }
    }
}

感谢@stevesliva的评论,我能够解决这个问题。我发现了一些关键的注意事项(部分原因可能是我对粘贴和拖放交互的无知)。

  1. 不需要子类化NSTokenField

  2. 我必须为令牌字段实现委托函数tokenField(tokenField: NSTokenField, readFromPasteboard pboard: NSPasteboard) -> [AnyObject]?

  3. 我必须改变拖动的开始来存储粘贴板的字符串值。似乎如果粘贴板没有字符串值,那么上面的委托函数永远不会被调用。

相关内容

  • 没有找到相关文章

最新更新