Dragging TableView Rows - cocoa

ValidateDrop method is not working.
func tableView(_ tableView: NSTableView, writeRowsWith rowIndexes: IndexSet, to pboard: NSPasteboard) -> Bool {
let data = NSKeyedArchiver.archivedData(withRootObject: rowIndexes)
pboard.declareTypes([NSPasteboard.PasteboardType(rawValue: "public.data")], owner: self)
pboard.setData(data, forType: NSPasteboard.PasteboardType(rawValue: "public.data"))
print("WriteRows")
return true
}
func tableView(_ tableView: NSTableView, validateDrop info: NSDraggingInfo, proposedRow row: Int, proposedDropOperation dropOperation: NSTableView.DropOperation) -> NSDragOperation {
if dropOperation == .above {
return .move
}
print("acceptDrop")
return []
}
"WriteRows" is printed but validatedRow doesn't work and doesn't print.
At the first attempt of dragging this message is printed.
2018-03-02 12:55:05.785644+0100 Plantilla[37119:1093734] MessageTracer: load_domain_whitelist_search_tree:73: Search tree file's format version number (0) is not supported
2018-03-02 12:55:05.785702+0100 Plantilla[37119:1093734] MessageTracer: Falling back to default whitelist

I missed to Register table view to a specifically allowed type of object which can be dragged. Found solution here:
tableView.registerForDraggedTypes([NSPasteboard.PasteboardType("public.data")])

Related

Drag and Drop not working in Cocoa

I've implemented the acceptDrop and the validateDrop functions, and also the registerForTypes, but when I drag an item it does not even show the plus sign.
extension Document: NSCollectionViewDelegate {
func collectionView(_ collectionView: NSCollectionView, validateDrop draggingInfo: NSDraggingInfo, proposedIndex proposedDropIndex: UnsafeMutablePointer<Int>, dropOperation proposedDropOperation: UnsafeMutablePointer<NSCollectionViewDropOperation>) -> NSDragOperation {
return NSDragOperation.copy
}
func collectionView(_ collectionView: NSCollectionView, acceptDrop draggingInfo: NSDraggingInfo, index: Int, dropOperation: NSCollectionViewDropOperation) -> Bool {
let pasteboard = draggingInfo.draggingPasteboard()
if pasteboard.types?.contains(NSURLPboardType) == true, let url = NSURL(from: pasteboard) as? URL {
do {
try self.addAttachmentAtURL(url)
attachmentsList.reloadData()
return true
} catch let error as NSError {
self.presentError(error)
return false
}
}
return false
}
}
override func windowControllerDidLoadNib(_ windowController: NSWindowController) {
self.attachmentsList.register(forDraggedTypes: [NSURLPboardType])
}

How to sort NSTableView with custom class data

I am using cell-based tableview to store custom class data, for example
class Person {
var name:String = ""
var age: Int = 0
}
And then use a NSMUtableArray to collect person1, person2 ... datas, call it dataArray.
Present Person name on column1 and age on column2, works fine and editable.
func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
if tableColumn?.identifier == "Name"
{
return (self.dataArray[row] as! Person).name
}
else if tableColumn?.identifier == "Age"
{
return (self.dataArray[row] as! Person).age
}
}
How can I sort each column with respected sortDescriptor?
I follow that fefernce but "sortDescriptorWithKey:tableColumn.identifier" always fail in my code, it can be passed if set the tableColumn.identifier to "self", it also confused me.
Below are my other code fragments.
func tableView(_ tableView: NSTableView, sortDescriptorsDidChange oldDescriptors: [NSSortDescriptor]) {
let newDescriptors = tableView.sortDescriptors
dataArray.sort(using: newDescriptors)
tableView.reloadData()
}
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
// Sort
for tableColumn in tableView.tableColumns {
let sortDescrptor = NSSortDescriptor.init(key: tableColumn.identifier, ascending: true, selector: #selector(NSString.caseInsensitiveCompare))
tableColumn.sortDescriptorPrototype = sortDescrptor
}
}

Not able to save multiple records with Realm

Goals
I'm trying to update a few records and delete them from NSTableView after that. http://take.ms/6r3IV
Expected Results
I expect that my records will be updated and NSTableView will be reloaded to reflect my changes.
Actual Results
My application crashes. http://take.ms/q6SWw
Steps to Reproduce
What are steps we can follow to reproduce this issue?
Code Sample
https://gist.github.com/msamoylov/27e1b6c9255b254f033f44d6de115d20
Version of Realm and Tooling
Realm version: 2.0.0 (installed as the Dynamic Framework)
Xcode version: 8.0 (8A218a)
macOS version: 10.12
It seems that I wasn't handling notifications properly. So, I ended up rewriting my code in this way:
import Cocoa
import RealmSwift
class ExerciseListViewController: NSViewController {
#IBOutlet weak var exerciseTableView: NSTableView!
let realm = try! Realm()
var exercises = try! Realm().objects(Exercise.self).filter("preferred = false").sorted(byProperty: "priority")
var notificationToken: NotificationToken? = nil
override func viewDidLoad() {
super.viewDidLoad()
exerciseTableView.dataSource = self
exerciseTableView.delegate = self
exerciseTableView.doubleAction = #selector(self.addPreferredExercises(_:))
notificationToken = exercises.addNotificationBlock { [weak self] (changes: RealmCollectionChange) in
guard let exerciseTableView = self?.exerciseTableView else { return }
switch changes {
case .initial:
exerciseTableView.reloadData()
break
case .update(_, let deletions, let insertions, _):
exerciseTableView.beginUpdates()
exerciseTableView.insertRows(at: IndexSet(insertions), withAnimation: .slideDown)
exerciseTableView.removeRows(at: IndexSet(deletions), withAnimation: .effectFade)
exerciseTableView.endUpdates()
if self?.exercises.count == 0 {
self?.dismiss(nil)
}
break
case .error(let error):
fatalError("\(error)")
break
}
}
}
deinit {
notificationToken?.stop()
}
#IBAction func addPreferredExercises(_ sender: AnyObject) {
if exerciseTableView.selectedRowIndexes.isEmpty {
let alert = NSAlert()
alert.messageText = "Hint"
alert.informativeText = "Please select at least one exercise from the list."
alert.alertStyle = .informational
alert.beginSheetModal(for: view.window!, completionHandler: nil)
}
try! realm.write {
for index in exerciseTableView.selectedRowIndexes {
if exercises.indices.contains(index) {
let exercise = exercises[index]
exercise.preferred = true
}
}
}
}
}
extension ExerciseListViewController: NSTableViewDataSource, NSTableViewDelegate {
func numberOfRows(in tableView: NSTableView) -> Int {
return exercises.count
}
func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
return exercises.indices.contains(row) ? exercises[row].name : nil
}
func tableView(_ tableView: NSTableView, toolTipFor cell: NSCell, rect: NSRectPointer, tableColumn: NSTableColumn?, row: Int, mouseLocation: NSPoint) -> String {
let exercise = exercises[row]
let comment = exercise.comment as String!
return comment!
}
}
It still doesn't work 100% correct with multiple selections, but at least it's not crashing the app anymore. For some reason exerciseTableView.selectedRowIndexes contains non-existing indexes.

NSOutlineView does not allow expansion

I have a simple NSOutlineView, init via swift, with 2 columns. I made the following very simple data source, hoping to test it this way, but maybe I this format is not allowable. I assume the table view only queries as needed, so that this won't cause an infinite loop.
The result is a 4 row, 2 column table layout with "Name" and "Value", but no expansion buttons.
I've implemented isExpandable as mentioned in the Obj-C post with similar name and added the columns.
Is there something more that I need to do to setup a NSOutlineView with expandable elements, or should I attempt another more realistic dataSource test:
import Cocoa
class OutlineDataSource : NSObject,NSOutlineViewDataSource
{
var a = "Name"
var b = "Value"
var column1 : NSTableColumn
var column2 : NSTableColumn
init(column1:NSTableColumn,column2:NSTableColumn) {
self.column1 = column1
self.column2 = column2
}
func outlineView(outlineView: NSOutlineView, numberOfChildrenOfItem item: AnyObject?) -> Int
{
return 4;
}
func outlineView(outlineView: NSOutlineView, child index: Int, ofItem item: AnyObject?) -> AnyObject
{
return a
}
func outlineView(outlineView: NSOutlineView, isItemExpandable item: AnyObject) -> Bool
{
return true;
}
func outlineView(outlineView: NSOutlineView, objectValueForTableColumn tableColumn: NSTableColumn?, byItem item: AnyObject?) -> AnyObject?
{
if (tableColumn == column1)
{
return a
}
return b
}
}
outlineTableColumn needs to be set on the outline view.

Drag & Drop Reorder Rows on NSTableView

I was just wondering if there was an easy way to set an NSTableView to allow it to reorder its rows without writing any pasteboard code. I only need it to be able to do this internally, within one table. I have no issue writing the pboard code, except that I'm fairly sure that I saw Interface Builder have a toggle for this somewhere / saw it working by default. It certainly seems like a common enough task.
Thanks
Set your table view's datasource to be a class that conforms to NSTableViewDataSource.
Put this in an appropriate place (-applicationWillFinishLaunching, -awakeFromNib, -viewDidLoad or something similar):
tableView.registerForDraggedTypes(["public.data"])
Then implement these three NSTableViewDataSource methods:
tableView:pasteboardWriterForRow:
tableView:validateDrop:proposedRow:proposedDropOperation:
tableView:acceptDrop:row:dropOperation:
Here is fully-working code that supports drag-and-drop reordering multiple rows:
func tableView(tableView: NSTableView, pasteboardWriterForRow row: Int) -> NSPasteboardWriting? {
let item = NSPasteboardItem()
item.setString(String(row), forType: "public.data")
return item
}
func tableView(tableView: NSTableView, validateDrop info: NSDraggingInfo, proposedRow row: Int, proposedDropOperation dropOperation: NSTableViewDropOperation) -> NSDragOperation {
if dropOperation == .Above {
return .Move
}
return .None
}
func tableView(tableView: NSTableView, acceptDrop info: NSDraggingInfo, row: Int, dropOperation: NSTableViewDropOperation) -> Bool {
var oldIndexes = [Int]()
info.enumerateDraggingItemsWithOptions([], forView: tableView, classes: [NSPasteboardItem.self], searchOptions: [:]) {
if let str = ($0.0.item as! NSPasteboardItem).stringForType("public.data"), index = Int(str) {
oldIndexes.append(index)
}
}
var oldIndexOffset = 0
var newIndexOffset = 0
// For simplicity, the code below uses `tableView.moveRowAtIndex` to move rows around directly.
// You may want to move rows in your content array and then call `tableView.reloadData()` instead.
tableView.beginUpdates()
for oldIndex in oldIndexes {
if oldIndex < row {
tableView.moveRowAtIndex(oldIndex + oldIndexOffset, toIndex: row - 1)
--oldIndexOffset
} else {
tableView.moveRowAtIndex(oldIndex, toIndex: row + newIndexOffset)
++newIndexOffset
}
}
tableView.endUpdates()
return true
}
Swift 3 version:
func tableView(_ tableView: NSTableView, pasteboardWriterForRow row: Int) -> NSPasteboardWriting? {
let item = NSPasteboardItem()
item.setString(String(row), forType: "private.table-row")
return item
}
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 oldIndexes = [Int]()
info.enumerateDraggingItems(options: [], for: tableView, classes: [NSPasteboardItem.self], searchOptions: [:]) {
if let str = ($0.0.item as! NSPasteboardItem).string(forType: "private.table-row"), let index = Int(str) {
oldIndexes.append(index)
}
}
var oldIndexOffset = 0
var newIndexOffset = 0
// For simplicity, the code below uses `tableView.moveRowAtIndex` to move rows around directly.
// You may want to move rows in your content array and then call `tableView.reloadData()` instead.
tableView.beginUpdates()
for oldIndex in oldIndexes {
if oldIndex < row {
tableView.moveRow(at: oldIndex + oldIndexOffset, to: row - 1)
oldIndexOffset -= 1
} else {
tableView.moveRow(at: oldIndex, to: row + newIndexOffset)
newIndexOffset += 1
}
}
tableView.endUpdates()
return true
}
If you take a look at the tool tip in IB you'll see that the option you refer to
- (BOOL)allowsColumnReordering
controls, well, column reordering. I do not believe there is any other way to do this other than the standard drag-and-drop API for table views.
EDIT: ( 2012-11-25 )
The answer refers to drag-and-drop reordering of NSTableViewColumns; and while it was the accepted answer at the time. It does not appear, now nearly 3 years on, to be correct. In service of making the information useful to searchers, I'll attempt to give the more correct answer.
There is no setting that allows drag and drop reordering of NSTableView rows in Interface Builder. You need to implement certain NSTableViewDataSource methods, including:
- tableView:acceptDrop:row:dropOperation:
- (NSDragOperation)tableView:(NSTableView *)aTableView validateDrop:(id < NSDraggingInfo >)info proposedRow:(NSInteger)row proposedDropOperation:(NSTableViewDropOperation)operation
- (BOOL)tableView:(NSTableView *)aTableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pboard
There are other SO question that address this reasonably thoroughly, including this one
Apple link to Drag and Drop APIs.
#Ethan's solution - Update Swift 4
in viewDidLoad :
private var dragDropType = NSPasteboard.PasteboardType(rawValue: "private.table-row")
override func viewDidLoad() {
super.viewDidLoad()
myTableView.delegate = self
myTableView.dataSource = self
myTableView.registerForDraggedTypes([dragDropType])
}
Later on delegate extension :
extension MyViewController: NSTableViewDelegate, NSTableViewDataSource {
// numerbOfRow and viewForTableColumn methods
func tableView(_ tableView: NSTableView, pasteboardWriterForRow row: Int) -> NSPasteboardWriting? {
let item = NSPasteboardItem()
item.setString(String(row), forType: self.dragDropType)
return item
}
func tableView(_ tableView: NSTableView, validateDrop info: NSDraggingInfo, proposedRow row: Int, proposedDropOperation dropOperation: NSTableView.DropOperation) -> NSDragOperation {
if dropOperation == .above {
return .move
}
return []
}
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.dragDropType), let index = Int(str) {
oldIndexes.append(index)
}
}
var oldIndexOffset = 0
var newIndexOffset = 0
// For simplicity, the code below uses `tableView.moveRowAtIndex` to move rows around directly.
// You may want to move rows in your content array and then call `tableView.reloadData()` instead.
tableView.beginUpdates()
for oldIndex in oldIndexes {
if oldIndex < row {
tableView.moveRow(at: oldIndex + oldIndexOffset, to: row - 1)
oldIndexOffset -= 1
} else {
tableView.moveRow(at: oldIndex, to: row + newIndexOffset)
newIndexOffset += 1
}
}
tableView.endUpdates()
return true
}
}
Plus, for those it may concerne:
If you want to disable certain cells from being dragable, return nil in pasteboardWriterForRows method
If you want to prevent drop a certain locations ( too far for instance ) just use return [] in validateDrop's method
Do not call tableView.reloadData() synchronously inside func tableView(_ tableView:, acceptDrop info:, row:, dropOperation:). This will disturb Drag and Drop animation, and can be very confusing. Find a way to wait until animation finishes, and async it's reloading
This answer covers Swift 3, View-based NSTableViews and single/multiple rows drag&drop reorder.
There are 2 main steps which must be performed in order to achieve this:
Register table view to a specifically allowed type of object which can be dragged.
tableView.register(forDraggedTypes: ["SomeType"])
Implement 3 NSTableViewDataSource methods: writeRowsWith, validateDrop and acceptDrop.
Before drag operation has started, store IndexSet with indexes of rows which will be dragged, in the pasteboard.
func tableView(_ tableView: NSTableView, writeRowsWith rowIndexes: IndexSet, to pboard: NSPasteboard) -> Bool {
let data = NSKeyedArchiver.archivedData(withRootObject: rowIndexes)
pboard.declareTypes(["SomeType"], owner: self)
pboard.setData(data, forType: "SomeType")
return true
}
Validate drop only if dragging operation is above of specified row. This ensures when dragging is performed other rows won't be highlighted when dragged row will float above them. Also, this fixes an AutoLayout issue.
func tableView(_ tableView: NSTableView, validateDrop info: NSDraggingInfo, proposedRow row: Int,
proposedDropOperation dropOperation: NSTableViewDropOperation) -> NSDragOperation {
if dropOperation == .above {
return .move
} else {
return []
}
}
When accepting drop just retrieve IndexSet that previously was saved in the pasteboard,
iterate through it and move rows using calculated indexes.
Note: Part with iteration and row moving I've copied from #Ethan's answer.
func tableView(_ tableView: NSTableView, acceptDrop info: NSDraggingInfo, row: Int, dropOperation: NSTableViewDropOperation) -> Bool {
let pasteboard = info.draggingPasteboard()
let pasteboardData = pasteboard.data(forType: "SomeType")
if let pasteboardData = pasteboardData {
if let rowIndexes = NSKeyedUnarchiver.unarchiveObject(with: pasteboardData) as? IndexSet {
var oldIndexOffset = 0
var newIndexOffset = 0
for oldIndex in rowIndexes {
if oldIndex < row {
// Dont' forget to update model
tableView.moveRow(at: oldIndex + oldIndexOffset, to: row - 1)
oldIndexOffset -= 1
} else {
// Dont' forget to update model
tableView.moveRow(at: oldIndex, to: row + newIndexOffset)
newIndexOffset += 1
}
}
}
}
return true
}
View-based NSTableViews update themselfs when moveRow is called, there is no need to use beginUpdates() and endUpdates() block.
Unfortunately you do have to write the Paste board code. The Drag and Drop API is fairly generic which makes it very flexible. However, if you just need reordering it's a bit over-the-top IMHO. But anyway, I have created a small sample project which has an NSOutlineView where you can add and remove items as well as reorder them.
This is not an NSTableView but the implementation of the Drag & Drop protocol is basically identical.
I implemented drag and Drop in one go so it's best to look at this commit.
If your are moving only one row at the time you can use the following code:
func tableView(_ tableView: NSTableView, acceptDrop info: NSDraggingInfo, row: Int, dropOperation: NSTableViewDropOperation) -> Bool {
let pasteboard = info.draggingPasteboard()
guard let pasteboardData = pasteboard.data(forType: basicTableViewDragAndDropDataType) else { return false }
guard let rowIndexes = NSKeyedUnarchiver.unarchiveObject(with: pasteboardData) as? IndexSet else { return false }
guard let oldIndex = rowIndexes.first else { return false }
let newIndex = oldIndex < row ? row - 1 : row
tableView.moveRow(at: oldIndex, to: newIndex)
// Dont' forget to update model
return true
}
This is an update to #Ethan's answer for Swift 3:
let dragDropTypeId = "public.data" // or any other UTI you want/need
func tableView(_ tableView: NSTableView, pasteboardWriterForRow row: Int) -> NSPasteboardWriting? {
let item = NSPasteboardItem()
item.setString(String(row), forType: dragDropTypeId)
return item
}
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 oldIndexes = [Int]()
info.enumerateDraggingItems(options: [], for: tableView, classes: [NSPasteboardItem.self], searchOptions: [:]) {
if let str = ($0.0.item as! NSPasteboardItem).string(forType: self.dragDropTypeId), let index = Int(str) {
oldIndexes.append(index)
}
}
var oldIndexOffset = 0
var newIndexOffset = 0
// For simplicity, the code below uses `tableView.moveRowAtIndex` to move rows around directly.
// You may want to move rows in your content array and then call `tableView.reloadData()` instead.
tableView.beginUpdates()
for oldIndex in oldIndexes {
if oldIndex < row {
tableView.moveRow(at: oldIndex + oldIndexOffset, to: row - 1)
oldIndexOffset -= 1
} else {
tableView.moveRow(at: oldIndex, to: row + newIndexOffset)
newIndexOffset += 1
}
}
tableView.endUpdates()
self.reloadDataIntoArrayController()
return true
}
Swift 5 solution. I had to add 'registerForDraggedTypes' method in viewDidLoad for this to work.
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
tableView.dataSource = self
tableView.delegate = self
// you must register the type you want to drag-n-drop! in this case 'strings'
tableView.registerForDraggedTypes([.string])
self.mapView.fitAll(in: teamManager.group.teams(), andShow: true)
}
extension ViewController : NSTableViewDataSource {
func numberOfRows(in tableView: NSTableView) -> Int {
return dataModel.count // or whatever
}
func tableView(_ tableView: NSTableView, pasteboardWriterForRow row: Int) -> NSPasteboardWriting? {
let pasteboard = NSPasteboardItem()
// in this example I'm dragging the row index. Once dropped i'll look up the value that is moving by using this.
// remember in viewdidload I registered strings so I must set strings to pasteboard
pasteboard.setString("\(row)", forType: .string)
return pasteboard
}
func tableView(_ tableView: NSTableView, validateDrop info: NSDraggingInfo, proposedRow row: Int, proposedDropOperation dropOperation: NSTableView.DropOperation) -> NSDragOperation {
let canDrop = (row > 2) // in this example you cannot drop on top two rows
print("valid drop \(row)? \(canDrop)")
if (canDrop) {
return .move //yes, you can drop on this row
}
else {
return [] // an empty array is the equivalent of nil or 'cannot drop'
}
}
func tableView(_ tableView: NSTableView, acceptDrop info: NSDraggingInfo, row: Int, dropOperation: NSTableView.DropOperation) -> Bool {
let pastboard = info.draggingPasteboard
if let sourceRowString = pastboard.string(forType: .string) {
print("from \(sourceRowString). dropping row \(row)")
return true
}
return false
}
}
Here is the fully working code in swift 5. Lets you move multiple items at once!
override func viewDidLoad() {
super.viewDidLoad()
myTableView.delegate = self
myTableView.dataSource = self
myTableView.registerForDraggedTypes([.string])
}
func tableView(_ tableView: NSTableView, pasteboardWriterForRow row: Int) -> NSPasteboardWriting? {
let pasteboard = NSPasteboardItem()
pasteboard.setString("\(row)", forType: .string)
return pasteboard
}
func tableView(_ tableView: NSTableView, validateDrop info: NSDraggingInfo, proposedRow row: Int, proposedDropOperation dropOperation: NSTableView.DropOperation) -> NSDragOperation {
return .move
}
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: .string), let index = Int(str) {
oldIndexes.append(index)
}
}
var oldIndexOffset = 0
var newIndexOffset = 0
// For simplicity, the code below uses `tableView.moveRowAtIndex` to move rows around directly.
// You may want to move rows in your content array and then call `tableView.reloadData()` instead.
tableView.beginUpdates()
for oldIndex in oldIndexes {
if oldIndex < row {
tableView.moveRow(at: oldIndex + oldIndexOffset, to: row - 1)
oldIndexOffset -= 1
} else {
tableView.moveRow(at: oldIndex, to: row + newIndexOffset)
newIndexOffset += 1
}
}
tableView.endUpdates()
return true
}
Hope it's not too late...
I work with VisualStudio for Mac in C# and don't have Swift skills...
Can you give me a transcription in C# of this part of you'r sample?
Thank tou for helping if possible
info.enumerateDraggingItems(options: [], for: tableView, classes: [NSPasteboardItem.self], searchOptions: [:]) { dragItem, _, _ in
if let str = (dragItem.item as? NSPasteboardItem)?.string(forType: .string), let index = Int(str) {
oldIndexes.append(index)
}
}

Resources