2016-04-20 33 views
7

Mam NSTableView, który z przerwami przestaje animować i aktualizować się poprawnie, co prowadzi do strasznego doświadczenia użytkownika.Niepodległa animacja NSTableView

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

Wydaje się, że brak logiki, gdy zatrzymuje animowanie, a także w wielu testach zrobiłem to czuje się prawie jak to zbudować powiązane. Co ciekawe, nigdy nie przestaje on animować, gdy profiluję ...

To tak, jakby coś w głównym wątku blokowało interfejs użytkownika, a następnie upłynął limit czasu NSTableView i anulowało aktualizację - ale nie mam pojęcia, jak mogę to debugować .

+0

Chyba wszystko, co można zrobić, to upewnić się, że wszystkie wyżej kod jest uruchomiony w głównym wątku (zapakuj go w 'dispatch_async (dispatch_get_main_queue(), {...}') i spróbuj wysłać pracę, która może blokować wątek w tle i sprawdzić, czy się poprawi.Może jakieś sprytnie umieszczone instrukcje dziennika pomogą ci upewnićsię, że ten kod jest wywoływany we właściwym czasie Widoki tabel są trudne do debugowania –

+4

To pytanie nie zawiera wystarczających informacji, aby odtworzyć problem Zobacz [mcve] – jtbandes

+1

Czy możesz dołączyć przykładowy projekt, który odtwarza problem? – JAL

Odpowiedz

1

Co jeśli zrobisz jedno, a potem drugie? Niedawno zrobiłem coś podobnego, gdy potrzebowałem wstawić komórkę ORAZ przewijać, co prowadzi do słabego doświadczenia użytkownika. Rozwiązaniem było dodanie niewielkiego opóźnienia. Nie wiem, czy to jest to, co starasz się osiągnąć bazę na małym fragmencie kodu, ale tutaj mamy przejść:

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

Dzięki Doug za to, że pomyślałeś - Wypróbowałem to, ale nie robi różnicy ... to jest naprawdę stra nge. – Chris

+0

Czy próbowałeś grać z różnymi opóźnieniami? Nie jestem obeznany ze składnią początku i końca aktualizacji, ale wygląda na to, że jest to przetwarzanie wsadowe. Czy próbowałeś eksperymentować z nieużywaniem go? –

+0

Nie wiem, dlaczego to skompilowane, ale właśnie zauważyłem, że używasz NSMutableIndexSet, kiedy myślę, że zamierzałeś użyć [NSIndexPath] ... lub może Set (odpowiednio tablica NSIndexPath lub Set of NSIndexPath). Jeśli to zadziała, daj mi znać, a ja przekażę to jako odpowiedź. –