我的应用中有NSTableView
和NSOutlineView
。用户应该能够将项目从大纲视图拖动到表格视图;如果它是可接受的操作(即所选行索引在粘贴板中),则表视图的目标行亮起。除了最初将项目拖入表格视图时,一切都有效。
接收表中的每个NSTableCellView
都有以下方法:
func dragContainsIndices(pasteboard: NSPasteboard) -> IndexSet {
if let types:[String] = pasteboard.types {
for type in types {
if type == BTVPBoardType { //_1
if let indexData: Data = pasteboard.data(forType: BTVPBoardType) {. //_2
let indicies: IndexSet = NSKeyedUnarchiver.unarchiveObject(with: indexData) as! IndexSet
if indicies.count > 0 {
return indicies
}
}
}
}
}
return IndexSet()
}
override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation {
let pastboard: NSPasteboard = sender.draggingPasteboard()
if self.dragContainsIndices(pasteboard: pastboard).count > 0 {
self.backingIcon.imageColour = .darkGreen //proprietary background colouring method
}
return .link
}
如果用户尝试将行从大纲视图拖到表格视图,则表格单元格视图中的draggingEntered(_:)
会运行,但dragContainsIndices(_:)
无法识别NSPasteboard
拥有任何数据,即使它包含正确的type
。 //_1
处的检查通过,但代码未找到任何数据。因此它返回一个空集,导致背景颜色不被更改。
如果没有发布任何内容,如果用户将该项目拖离单元格然后再返回该单元格,那么索引集将正确展开并且颜色会发生变化。
在NSTableView
中,我使用theses方法提供了拖动会话:
override func mouseDragged(with event: NSEvent) {
let mouseDown = self.mouseDownEvent.locationInWindow
let dragPoint = event.locationInWindow
let dragDistance = hypot(mouseDown.x - dragPoint.x, mouseDown.y - dragPoint.y)
if dragDistance < 3 || self.selectedRowIndexes.count < 1 {
return
}
let pboardItem: NSPasteboardItem = NSPasteboardItem()
if pboardItem.setDataProvider(self, forTypes: [BTVPBoardType]) {
Swift.print ("Set data")
}
let dragItem: NSDraggingItem = NSDraggingItem(pasteboardWriter: pboardItem)
var dragPos = self.convert(event.locationInWindow, from: nil)
dragImage = NSImage.init(named: NSImageNameMultipleDocuments)!
dragPos.x += dragImage.size.width
dragPos.y += dragImage.size.height
dragItem.imageComponentsProvider = {
let component = NSDraggingImageComponent(key: NSDraggingImageComponentIconKey)
component.contents = self.dragImage
component.frame = NSRect(origin: NSPoint(), size: self.dragImage.size)
return [component]
}
beginDraggingSession(with: [dragItem], event: event, source: self)
}
func pasteboard(_ pasteboard: NSPasteboard?, item: NSPasteboardItem, provideDataForType type: String) {
if files.count < 1 {return} //don't bother if there's no
if let pasteboard = pasteboard {
pasteboard.declareTypes([BTVPBoardType], owner: self)
let _: Int = pasteboard.clearContents()
let indices = self.selectedRowIndexes
pasteboard.setData(NSKeyedArchiver.archivedData(withRootObject: indices), forType: BTVPBoardType)
Swift.print("written objects") //always writes indices
}
}
pasteboard(_ pasteboard: NSPasteboard?, item: NSPasteboardItem, provideDataForType type: String)
是否与延迟抓取有关?出于某种原因,我在Mac上有一个拖拽和拖放的头部障碍。