I have a NSTableView which intermittently will stop animating and updating itself correctly, leading to a terrible user experience.
let oldRows = filteredDocuments
let newRows = newFilteredDocuments
let diff = oldRows.diff(newRows)
filteredDocuments = newFilteredDocuments
if (diff.results.count > 0) {
let deletionIndexPaths = NSMutableIndexSet()
diff.deletions.forEach { deletionIndexPaths.addIndex($0.idx) }
let insertionIndexPaths = NSMutableIndexSet()
diff.insertions.forEach { insertionIndexPaths.addIndex($0.idx) }
self.tableView?.beginUpdates()
self.tableView?.removeRowsAtIndexes(deletionIndexPaths, withAnimation: NSTableViewAnimationOptions.EffectFade)
self.tableView?.insertRowsAtIndexes(insertionIndexPaths, withAnimation: NSTableViewAnimationOptions.SlideLeft)
self.tableView?.endUpdates()
}
There seems to be no logic to when it stops animating, and in the many tests I've done it feels almost like it's build related. Interestingly it never stops animating when I am profiling...
It's as if something on the main thread is clogging up the UI and then the NSTableView times out and cancels the update - but I have no idea how I can debug this.
How about if you do one and then the other? I just recently did something similar when I needed to insert a cell AND scroll, which lead to a poor user experience. The solution was to add a slight delay. Not sure if this is what you're trying to accomplish base on the small code snippet, but here we go:
let oldRows = filteredDocuments
let newRows = newFilteredDocuments
let diff = oldRows.diff(newRows)
filteredDocuments = newFilteredDocuments
if (diff.results.count > 0) {
let deletionIndexPaths = NSMutableIndexSet()
diff.deletions.forEach { deletionIndexPaths.addIndex($0.idx) }
let insertionIndexPaths = NSMutableIndexSet()
diff.insertions.forEach { insertionIndexPaths.addIndex($0.idx) }
self.tableView?.beginUpdates()
self.tableView?.removeRowsAtIndexes(deletionIndexPaths, withAnimation: NSTableViewAnimationOptions.EffectFade)
self.tableView?.endUpdates()
let delay = 0.35
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC))) // Hate this syntax
dispatch_after(delay, dispatch_get_main_queue(), { [weak self] in
self?.tableView?.beginUpdates()
self?.tableView?.insertRowsAtIndexes(insertionIndexPaths, withAnimation: NSTableViewAnimationOptions.SlideLeft)
self?.tableView?.endUpdates()
})
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With