2016-07-26 15 views
7

In meiner UICollectionView verwende ich ein einfaches Array von benutzerdefinierten Objekten zum Erstellen und Anzeigen von Zellen. Gelegentlich ändern sich diese Daten und ich möchte die Änderungen auf einmal animieren. Ich habe gewählt, dies zu tun, indem ich alle Änderungen in einem zweiten Array verfolge, indem ich die zwei verschiebe, und einen Satz von Verschiebungs-, Einfügungs-, Lösch- und Aktualisierungsoperationen innerhalb eines performBatchUpdates Blocks produziere. Ich weiß jetzt, dass es ziemlich schwierig ist, all diese Dinge im selben Block zu tun, weil man sich um Befehle von Operationen mit Indizes sorgen muss. In der Tat ist die angenommene Antwort auf this issue falsch (aber in den Kommentaren korrigiert).Wie werden Verschiebungen, Einfügungen, Löschungen und Aktualisierungen in einem UICollectionView performBatchUpdates-Block angeordnet?

Die Dokumentation scheint ziemlich fehlt, aber es deckt einen Fall:

Löschungen werden verarbeitet, bevor Einsätze in Batch-Operationen. Das bedeutet Die Indizes für die Löschvorgänge werden relativ zu den Indizes des Sammlungsansichtszustands vor der Stapelverarbeitung verarbeitet, und die Indizes für die Einfügungen werden relativ zu den Indizes der Status nach allen Löschungen in der Stapeloperation verarbeitet .

Das Dokument spricht jedoch nicht darüber, wann Bewegungen verarbeitet werden. Wenn ich moveItemAtIndexPath und deleteItemsAtIndexPaths im selben performBatchUpdates rufe, sollten die Verschiebungsindizes relativ zu der vorher oder nachher gelöschten Reihenfolge sein? Wie wäre es mit insertItemsAtIndexPaths?

Schließlich bin ich Fragen, mit denen reloadItemsAtIndexPaths und moveItemAtIndexPath in derselben Operation Aufruf:

Fatal Exception: NSInternalInconsistencyException Versuch zu löschen und neu zu laden den gleichen Indexpfad

Gibt es eine Möglichkeit alle Operationen, die ich will, in der gleichen performBatchUpdates tun? Wenn ja, in welcher Reihenfolge werden die Aktualisierungen relativ zu den anderen verarbeitet? Wenn nicht, was machen die Leute normalerweise? Laden Sie die Daten nach allen anderen Operationen neu? Vor? Mir wäre es viel lieber, wenn alle Animationen in einer einzigen Phase stattfinden würden.

Antwort

5

Für die Verschiebeoperationen ist der IndexPfad Pre-Delete-Indizes und der IndexPath ist Post-Delete-Index. Reloads sollten nur für Indexpfade angegeben werden, die nicht eingefügt, gelöscht oder verschoben wurden. Dies ist wahrscheinlich, warum Sie die NSInternalInconsistencyException sehen.

Ein praktischer Weg, um die Operationen zu überprüfen, sind korrekt eingerichtet: Die Reload-, Insert- und Move-to-indexPath-Dateien sollten keine Duplikate enthalten und die Reload-, Delete- und Move-from-IndexPfads sollten keine haben Duplikate.

UPDATE:

Es scheint, dass Elemente, die Sie bewegen, werden nicht ebenfalls aktualisiert, sondern nur verschoben. Wenn Sie also ein Element aktualisieren und verschieben müssen, können Sie das Reload vor oder nach der Stapelaktualisierung durchführen (abhängig vom Status Ihrer Datenquelle).

+0

Also sagen wir, ich habe eine Zelle, die aktualisiert werden muss, weil sie anders angezeigt wird (andere Farbe zum Beispiel), und ich muss sie auch verschieben. Dies ist ein Beispiel, wo ich mich bewegen und neu laden muss. Gibt es eine Möglichkeit, diese im selben Animationsblock zu machen? –

+0

Da Sie den Umzug durchführen, wird die Zelle automatisch neu geladen. Sie müssen es nicht explizit neu laden. – Mark

+0

Oh! Ich habe es nicht bemerkt (und ich schätze, ich habe es versäumt, diesen Fall zu experimentieren).Ich nahm an, dass es nur die Inhaltscontainer verschieben würde, ohne sie neu zu laden. –