UICollectionView-Zellen werden nach abgebrochenen Ziehsitzungen an der gleichen Stelle angezeigt

8

Ich habe Probleme mit einem obskuren Problem, das das lokale Ziehen und Ablegen in einem UICollectionViewController implementiert. Die Sammlungsansicht ermöglicht das Ziehen von Elementen in und aus Ordnern. Alles sieht gut aus und funktioniert gut, bis abgebrochene Dragons ausgeführt werden.

Schritte zum Reproduzieren:

  1. Sammeln Sie eine Anzahl von Elementen in einer Drag-Sitzung.
  2. Brechen Sie das Ziehen ab, indem Sie beispielsweise zum Bildschirmrand wechseln.
  3. Sammeln Sie eine Anzahl von Elementen in einer Drag-Sitzung (kann einige der oben abgebrochenen Elemente enthalten).
  4. Legen Sie die Elemente in einem Ordner weiter oben in der Sammlungsansicht ab, sodass die entfernten Elemente in der Sitzung eine Neupositionierung der Elemente im abgebrochenen Ziehen bewirken.

Die Elemente der abgebrochenen Sitzung werden nun scheinbar hinter anderen Zellen angezeigt. Sie sind jedoch keine echten Zellen, wie durch Drehen des iPads zu sehen ist, diese "Geister" -Zellen rotieren nicht richtig mit den echten Zellen, hinter denen sie sich befinden, sie rotieren, als ob ihr Ursprung fest ist. Sie können auch nicht in irgendeiner Art und Weise interagiert werden und die Datenquellenmethoden stellen keine Anfragen für sie. In bestimmten Situationen können sie auch nach dem Ende der realen Zellen gesehen werden, indem sie die Ansicht nach oben ziehen (sie springt zurück und versteckt sie nach dem Loslassen). Eine große Anzahl abgebrochener Verschiebungen führt auch zu einer sehr schlechten Scrollleistung, selbst wenn die meisten echten Zellen aus der Sammlungsansicht herausgezogen werden.

Ich habe versucht, den gesamten UICollectionViewController und seine Zelle im Storyboard neu zu erstellen. Dies ist kein Fall, in dem nicht alle Zelleneigenschaften eingestellt werden (ich wünschte, es wäre), da die Geisterzellen alle Elemente enthalten. Sie können auch abhängig von den durchgeführten Operationen mehrfach überlagert werden. Bitte sehen Sie Screenshots.

Beim häufigen Ziehen und Ablegen von Hunderten von Elementen in die Sammlungsansicht und aus der Sammlungsansicht wurden keine Probleme gefunden. Erst nach einem abgebrochenen Ziehen erscheint das Problem.

Meine beste Vermutung in diesem Stadium ist, dass die Geisterzellen Teil der Abbruchanimation sind, die nach Abschluss nicht entfernt wurden. Da es keine API-Interaktion mit den Drag & Drop-Animationen gibt, weiß ich nicht, wie ich das testen oder beheben kann.

Was ich im Controller implementiere:

  1. itemsForBeginningDragSession und itemsForAddingToDragSession, die beide einen einzelnen NSItemProvider zum zurückgegebenen Array hinzufügen.
  2. dragPreviewParametersForItemAtIndexPath legt den sichtbaren Pfad fest. (Das Entfernen dieser Methode ist für das Problem nicht relevant)
  3. dropSessionDidUpdate gibt entweder UIDropOperationMove, UICollectionViewDropIntentInsertIntoDestinationIndexPath oder UIDropOperationForbidden zurück, wenn die Sitzung nicht lokal ist.
  4. performDropWithCoordinator verwendet performBatchUpdates und ruft dropItem für jedes Element auf. (Das Problem besteht weiterhin ohne dropItem und mit einer unreinen Sammlungsansicht reloadSections!)

Was ich benutze:

Xcode 9.2, verschiedene iPads mit iOS 11.2 und 11.2.5

Ich bin jetzt seit fünf Tagen solid, also werden alle Hinweise in die richtige Richtung sehr geschätzt.

Zellen überlagert zweimal (ähnliches Bild in drei Fällen):

Zellen, die dreimal überlagert sind (die erste Zelle hat drei eindeutige Bilder):

Zellen, die mehrfach überlagert sind:

Im Folgenden finden Sie den Code für den einfacheren Fall, in dem Dateien in einen vorhandenen Ordner gezogen werden, da dies die Eingabe der Quelle erleichtert:

%Vor%

Log-Sitzung 1-1. Beachten Sie, dass die Anzahl der draggingItems (6) mit der Anzahl der Einträge in cellAppearanceStatesByIndexPaths (6) übereinstimmt, unabhängig davon, was:

ist %Vor%

Dann folgten mehrere abgebrochene Drags.

Log-Sitzung 1-2. Beachten Sie erneut, dass die Anzahl der draggingItems (8) mit der Anzahl der Einträge in cellAppearanceStatesByIndexPaths (8) übereinstimmt:

%Vor%

Dann folgten einige mehr abgebrochene Drags.

Log-Sitzung 1-3. Dies ist, wenn die überlagerten Zellen erschienen. Der Schlüssel hier ist, glaube ich, dass die Anzahl von draggingItems (4) sehr verschieden von cellAppearanceStatesByIndexPaths (25) ist, die viele Indexpfade enthält, die in dieser Sitzung nicht gezogen wurden:

%Vor%

Basierend auf dem Verhalten und diesen Logs glaube ich, dass die Interna des Drag-Tracker der Sammelansicht beschädigt sind. Warum ist die Schlüsselfrage?

UPDATE: Dieses Problem wurde erfolgreich in einer eigenständigen / minimalen Implementierung mit sehr wenig Code reproduziert: Test.zip

UPDATE: In diesem Video wird gezeigt, wie Sie das Problem mit dem Testprojekt reproduzieren können: reproducing_issue.mp4

    
Derek Pollard 13.02.2018, 16:51
quelle

0 Antworten