2016-04-20 26 views
7

Possiedo un NSTableView che interrompe a intermittenza l'animazione e l'aggiornamento in modo corretto, causando un'esperienza utente terribile.Animazione NSTableView incoerente

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() 
} 

Non sembra esserci alcuna logica a quando si ferma l'animazione, e nei numerosi test che ho fatto ci si sente quasi come se fosse a costruire relativo. È interessante notare che non smette mai di animare quando sto profilando ...

È come se qualcosa sul thread principale intasasse l'interfaccia utente e quindi NSTableView andasse in timeout e annulli l'aggiornamento - ma non ho idea di come sia possibile eseguire il debug di questo .

+0

Credo che tutto si può fare è assicurarsi che tutto il codice di cui sopra è in esecuzione sul thread principale (avvolgilo in 'dispatch_async (dispatch_get_main_queue(), {...}') e prova il dispacciamento del lavoro che potrebbe bloccare un thread in background e vedere se migliora. Forse alcune istruzioni di log posizionate in modo intelligente ti aiuteranno a garantire che questo codice venga chiamato al momento giusto Le viste in tabella sono difficili da eseguire per il debug. –

+4

Questa domanda non contiene informazioni sufficienti per riprodurre il problema. [mcve] – jtbandes

+1

Puoi allegare un progetto di esempio che riproduce il problema? – JAL

risposta

1

Che ne dici se ne fai uno e poi l'altro? Recentemente ho fatto qualcosa di simile quando ho avuto bisogno di inserire una cella AND scroll, che porta a una scarsa esperienza utente. La soluzione era di aggiungere un leggero ritardo. Non so se questo è quello che stai cercando di realizzare base sul piccolo frammento di codice, ma qui andiamo:

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() 
    }) 
} 
+0

Grazie Doug per il tuo pensiero - L'ho provato ma non fa differenza ... è davvero stra ESN. – Chris

+0

Hai provato a giocare con tempi di ritardo diversi? Non ho familiarità con la sintassi degli aggiornamenti di inizio e fine, ma sembra che sia per qualche elaborazione in batch. Hai provato a sperimentare senza usarlo? –

+0

Non sono sicuro del motivo per cui è stato compilato, ma ho appena notato che si sta utilizzando NSMutableIndexSet, quando penso che si intendesse utilizzare [NSIndexPath] ... o forse Set (una serie di NSIndexPath o un Set di NSIndexPath, rispettivamente). Se funziona, fammelo sapere e lo invierò come risposta. –