Skip to content

Commit 4139c9e

Browse files
committed
Fix batch moving of rows in NSTableView
`NSTableView` doesn't support batch updating so every change (insert, delete, move) may alter its row indexes, making it difficult to apply moves generated from a `StagedChangeset` unless indexes are corrected accordingly and it is ensured that inserts are always performed after any moves.
1 parent 8d45ea9 commit 4139c9e

File tree

1 file changed

+14
-6
lines changed

1 file changed

+14
-6
lines changed

Sources/Extensions/AppKitExtension.swift

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,16 +73,24 @@ public extension NSTableView {
7373
removeRows(at: IndexSet(changeset.elementDeleted.map { $0.element }), withAnimation: deleteRowsAnimation())
7474
}
7575

76-
if !changeset.elementInserted.isEmpty {
77-
insertRows(at: IndexSet(changeset.elementInserted.map { $0.element }), withAnimation: insertRowsAnimation())
78-
}
79-
8076
if !changeset.elementUpdated.isEmpty {
8177
reloadData(forRowIndexes: IndexSet(changeset.elementUpdated.map { $0.element }), columnIndexes: IndexSet(0..<tableColumns.count))
8278
}
8379

84-
for (source, target) in changeset.elementMoved {
85-
moveRow(at: source.element, to: target.element)
80+
if !changeset.elementMoved.isEmpty {
81+
let insertionIndices = IndexSet(changeset.elementInserted.map { $0.element })
82+
var movedSourceIndices = IndexSet()
83+
84+
for (source, target) in changeset.elementMoved {
85+
let sourceElementOffset = movedSourceIndices.count(in: source.element...)
86+
let targetElementOffset = insertionIndices.count(in: 0..<target.element)
87+
moveRow(at: source.element + sourceElementOffset, to: target.element - targetElementOffset)
88+
movedSourceIndices.insert(source.element)
89+
}
90+
}
91+
92+
if !changeset.elementInserted.isEmpty {
93+
insertRows(at: IndexSet(changeset.elementInserted.map { $0.element }), withAnimation: insertRowsAnimation())
8694
}
8795

8896
endUpdates()

0 commit comments

Comments
 (0)