我使用swift 3 for osx,我正在不同的视图控制器中搜索两个NSTableViews之间的拖放解决方案。
我有一个简单的工作解决方案,每个tableview只有一列,没有自定义单元格视图和字符串值。
SourceTableView
width of containing box - left - right
TargetTableView
import Cocoa
class SourceTableView: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
@IBOutlet weak var leftTableView: NSTableView!
var dataArray: NSMutableArray = ["Item 1","Item 2","Item 3"]
let pbStringType = "NSPasteBoardStringType"
let pbIndexType = "NSPasteBoardIndexType"
func numberOfRows(in tableView: NSTableView) -> Int {
return dataArray.count
}
func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
return dataArray[row]
}
func tableView(_ tableView: NSTableView, writeRowsWith rowIndexes: IndexSet, to pboard: NSPasteboard) -> Bool {
let data = (dataArray as NSArray).objects(at:rowIndexes as IndexSet)
pboard.declareTypes([pbStringType, pbIndexType], owner: nil)
pboard.setData(NSKeyedArchiver.archivedData(withRootObject: data), forType: pbStringType)
pboard.setData(NSKeyedArchiver.archivedData(withRootObject: rowIndexes), forType: pbIndexType)
return true
}
}
但是现在我需要针对以下情况的解决方案:
我通过核心数据获得的值:
import Cocoa
class TargetVC2: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
@IBOutlet weak var rightTableView: NSTableView!
var dataArray: NSMutableArray = ["Item 5", "Item 6", "Item 7"]
let pbStringType = "NSPasteBoardStringType"
let pbIndexType = "NSPasteBoardIndexType"
override func viewDidLoad() {
super.viewDidLoad()
rightTableView.register(forDraggedTypes: [pbStringType])
}
func numberOfRows(in tableView: NSTableView) -> Int {
return dataArray.count
}
func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
return dataArray[row]
}
func tableView(_ tableView: NSTableView, writeRowsWith rowIndexes: IndexSet, to pboard: NSPasteboard) -> Bool {
let data = dataArray.objects(at:rowIndexes as IndexSet)
pboard.declareTypes([pbStringType, pbIndexType], owner: nil)
pboard.setData(NSKeyedArchiver.archivedData(withRootObject: data), forType: pbStringType)
pboard.setData(NSKeyedArchiver.archivedData(withRootObject: rowIndexes), forType: pbIndexType)
return true
}
func tableView(_ tableView: NSTableView, validateDrop info: NSDraggingInfo, proposedRow row: Int, proposedDropOperation dropOperation: NSTableViewDropOperation) -> NSDragOperation {
if dropOperation == .above {
return .move
}
return []
}
func tableView(_ tableView: NSTableView, acceptDrop info: NSDraggingInfo, row: Int, dropOperation: NSTableViewDropOperation) -> Bool {
var dropRow = row
if info.draggingSource() as! NSTableView == rightTableView && tableView == rightTableView && dropOperation == .above {
let data = info.draggingPasteboard().data(forType: pbIndexType)!
let rowIndexes = NSKeyedUnarchiver.unarchiveObject(with: data) as! NSIndexSet
dataArray.removeObjects(at: rowIndexes as IndexSet)
dropRow -= rowIndexes.countOfIndexes(in: NSMakeRange(0, dropRow))
}
let data = info.draggingPasteboard().data(forType: pbStringType)!
let draggedStrings = NSKeyedUnarchiver.unarchiveObject(with: data) as! [Any]
dataArray.insert(draggedStrings, at:IndexSet(integersIn:dropRow..<(dropRow + draggedStrings.count)))
rightTableView.reloadData()
return true
}
}
但我的上述解决方案并不适用于我的新#34;愿望方案&#34;
更新 例如:我修改了我的SourceTabelView:
func requestValues() {
var values= [Person]()
let appdelegate = NSApplication.shared().delegate as! AppDelegate
let context = appdelegate.persistentContainer.viewContext
let request = NSFetchRequest<Person>(entityName: "Person")
do {
values = try context.fetch(request)
SourceTableView.reloadData()
} catch { }
}
它工作正常,但如果我拖动行的值为&#34; Max&#34; =&GT;我的应用程序因此错误而崩溃:
import Cocoa
struct structData {
var firstname:String
var secondname:String
}
class SourceVC: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
@IBOutlet weak var leftTableView: NSTableView!
var people = [structData]()
let pbStringType = "NSPasteBoardStringType"
let pbIndexType = "NSPasteBoardIndexType"
override func viewDidLoad() {
people.append(structData(firstname:"Max",secondname:"Mustermann"))
}
func numberOfRows(in tableView: NSTableView) -> Int {
return people.count
}
func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
return people[row].firstname
}
func tableView(_ tableView: NSTableView, writeRowsWith rowIndexes: IndexSet, to pboard: NSPasteboard) -> Bool {
let data = (people as NSArray).objects(at:rowIndexes as IndexSet)
pboard.declareTypes([pbStringType, pbIndexType], owner: nil)
pboard.setData(NSKeyedArchiver.archivedData(withRootObject: data), forType: pbStringType)
pboard.setData(NSKeyedArchiver.archivedData(withRootObject: rowIndexes), forType: pbIndexType)
return true
}
}