我有一个NSTableView
可以拖放表格行来重新排序的地方。这可以通过在我的视图控制器中设置拖动类型来实现:
@IBOutlet weak var tableView: NSTableView!
let dragType = NSPasteboard.PasteboardType(rawValue: "myapp.task")
override func viewDidLoad() {
super.viewDidLoad()
tableView.registerForDraggedTypes([dragType])
}
...然后使用这些表委托方法实现重新排序:
//Start drag
func tableView(_ tableView: NSTableView, pasteboardWriterForRow row: Int) -> NSPasteboardWriting? {
let item = NSPasteboardItem()
item.setString(String(row), forType: dragType)
return item
}
//Verify proposed drop
func tableView(_ tableView: NSTableView, validateDrop info: NSDraggingInfo, proposedRow row: Int, proposedDropOperation dropOperation: NSTableView.DropOperation) -> NSDragOperation {
if dropOperation == .above {
return .move
}else{
return []
}
}
//Accept drop of one or multiple rows
func tableView(_ tableView: NSTableView, acceptDrop info: NSDraggingInfo, row: Int, dropOperation: NSTableView.DropOperation) -> Bool {
var oldIndexes = [Int]()
info.enumerateDraggingItems(options: [], for: tableView, classes: [NSPasteboardItem.self], searchOptions: [:]) { dragItem, _, _ in
if let str = (dragItem.item as! NSPasteboardItem).string(forType: self.dragType), let index = Int(str) {
oldIndexes.append(index)
}
}
//Do a bunch of logic to reorder the table rows...
}
现在,除了重新排序我的表格行之外,我还希望能够将一行拖放到我的应用程序中的其他位置——有点像将行移动到不同的地方。
我有一个自定义NSView
设置作为拖动目标,我可以拖动一个表格行,并且自定义视图会适当地对拖过它的表格行做出反应:
class MyCustomView: NSView{
required init?(coder: NSCoder) {
super.init(coder: coder)
let taskDragType = NSPasteboard.PasteboardType(rawValue: "myapp.task")
registerForDraggedTypes([taskDragType])
}
override func draggingEntered(_ sender: NSDraggingInfo) -> NSDragOperation {
//...
}
override func draggingExited(_ sender: NSDraggingInfo?) {
//...
}
}
但我不清楚的部分是如何获取表行,以及在NSTableCellView
发生丢弃时将其关联对象设置为 上的属性:
//This is another method in MyCustomView
override func performDragOperation(_ draggingInfo: NSDraggingInfo) -> Bool {
guard let items = draggingInfo.draggingPasteboard.pasteboardItems else{ return false }
for item in items{
print("---")
print(item) //<-- NSPasteboardItem
let index = item.propertyList(forType: NSPasteboard.PasteboardType(rawValue: "myapp.task"))
print(index) //<-- Index of the table row
//How can I also get the task object associated with the row?
}
}
我可以获取行的索引,但我需要的是行数据源中的整个对象,因此我可以对它所代表的对象采取行动。我怀疑我需要更改pasteboardWriterForRow
将对象放在粘贴板上的方式,但我不确定该怎么做。
如何将行索引和对象都传递给粘贴板?