Ich habe meine Apps so aktualisiert, dass sie unter iOS 7 laufen, was größtenteils reibungslos funktioniert. Ich habe in mehr als einer App festgestellt, dass sich die reloadData
Methode von a UICollectionViewController
nicht mehr so verhält wie früher.
Ich werde das laden UICollectionViewController
, das UICollectionView
mit einigen Daten wie gewohnt füllen. Dies funktioniert beim ersten Mal hervorragend. Wenn ich jedoch neue Daten anfordere (füllen Sie die aus UICollectionViewDataSource
) und dann aufrufe reloadData
, wird die Datenquelle nach numberOfItemsInSection
und abgefragt numberOfSectionsInCollectionView
, aber es scheint nicht cellForItemAtIndexPath
die richtige Anzahl von Malen aufzurufen .
Wenn ich den Code so ändere, dass nur ein Abschnitt neu geladen wird, funktioniert er ordnungsgemäß. Das ist für mich kein Problem, diese zu ändern, aber ich denke nicht, dass ich das muss. reloadData
sollte alle sichtbaren Zellen gemäß der Dokumentation neu laden.
Hat das noch jemand gesehen?
quelle
reloadData
nach viewDidAppear das Problem zu lösen scheint, seine schreckliche Problemumgehung und eine Lösung erforderlich ist. Ich hoffe, hier hilft jemand.Antworten:
Erzwinge dies auf dem Haupt-Thread:
quelle
In meinem Fall hat sich die Anzahl der Zellen / Abschnitte in der Datenquelle nie geändert, und ich wollte nur den sichtbaren Inhalt auf dem Bildschirm neu laden.
Ich habe es geschafft, dies zu umgehen, indem ich angerufen habe:
dann:
quelle
performBatchUpdates:completion:
Block zu setzen?Ich hatte genau das gleiche Problem, aber ich konnte herausfinden, was falsch lief. In meinem Fall habe ich reloadData aus der collectionView aufgerufen: cellForItemAtIndexPath: was nicht korrekt zu sein scheint .
Das Versenden des Aufrufs von reloadData an die Hauptwarteschlange hat das Problem ein für alle Mal behoben.
quelle
reloadData
wurde es von einem Änderungsbeobachter angerufen.collectionView(_:willDisplayCell:forItemAtIndexPath:)
Das Nachladen einiger Elemente hat bei mir nicht funktioniert. In meinem Fall und nur weil die von mir verwendete collectionView nur einen Abschnitt enthält, lade ich diesen bestimmten Abschnitt einfach neu. Diesmal werden die Inhalte korrekt neu geladen. Seltsam, dass dies nur unter iOS 7 (7.0.3) geschieht.
quelle
Ich hatte das gleiche Problem mit reloadData unter iOS 7. Nach einer langen Debug-Sitzung fand ich das Problem.
Unter iOS7 bricht reloadData in UICollectionView frühere Updates, die noch nicht abgeschlossen wurden, nicht ab (Updates, die innerhalb von performBatchUpdates: block aufgerufen wurden).
Die beste Lösung, um diesen Fehler zu beheben, besteht darin, alle aktuell verarbeiteten Updates zu stoppen und reloadData aufzurufen. Ich habe keine Möglichkeit gefunden, einen Block von performBatchUpdates abzubrechen oder zu stoppen. Um den Fehler zu beheben, habe ich daher ein Flag gespeichert, das angibt, ob ein performBatchUpdates-Block vorhanden ist, der gerade verarbeitet wird. Wenn es keinen Update-Block gibt, der gerade verarbeitet wird, kann ich reloadData sofort aufrufen und alles funktioniert wie erwartet. Wenn es einen Update-Block gibt, der gerade verarbeitet wird, rufe ich reloadData für den gesamten Block von performBatchUpdates auf.
quelle
Swift 5 - 4 - 3
Swift 2
quelle
Ich hatte auch dieses Problem. Zufällig habe ich oben in der Sammlungsansicht eine Schaltfläche hinzugefügt, um das Neuladen zum Testen zu erzwingen - und plötzlich wurden die Methoden aufgerufen.
Fügen Sie auch einfach etwas hinzu, das so einfach ist wie
würde dazu führen, dass die Methoden aufgerufen werden
Außerdem habe ich mit der Rahmengröße herumgespielt - und voila, die Methoden wurden aufgerufen.
Es gibt viele Fehler mit iOS7 UICollectionView.
quelle
Sie können diese Methode verwenden
Sie können alle
indexPath
Objekte IhresUICollectionView
Arrays in das ArrayarrayOfAllIndexPaths
einfügen, indem Sie die Schleife für alle Abschnitte und Zeilen mithilfe der folgenden Methode iterierenIch hoffe du hast es verstanden und es kann dein Problem lösen. Wenn Sie weitere Erklärungen benötigen, antworten Sie bitte.
quelle
Die Lösung von Shaunti Fondrisi ist nahezu perfekt. Aber solch ein Code oder Codes wie das Einreihen der Ausführung von
UICollectionView
'sreloadData()
inNSOperationQueue
' smainQueue
setzen den Ausführungszeitpunkt tatsächlich an den Anfang der nächsten Ereignisschleife in der Ausführungsschleife, wodurch dieUICollectionView
Aktualisierung mit einem Flick bewirken könnte.Um dieses Problem zu lösen. Wir müssen den Ausführungszeitpunkt desselben Codeteils an das Ende der aktuellen Ereignisschleife setzen, aber nicht an den Anfang der nächsten. Und das können wir erreichen, indem wir davon Gebrauch machen
CFRunLoopObserver
.CFRunLoopObserver
beobachtet alle Warteaktivitäten der Eingabequelle und die Ein- und Ausstiegsaktivität der Ausführungsschleife.Unter diesen Aktivitäten
.AfterWaiting
kann beobachtet werden, wann die aktuelle Ereignisschleife kurz vor dem Ende steht, und.BeforeWaiting
kann beobachtet werden, wenn die nächste Ereignisschleife gerade begonnen hat.Da es nur eine
NSRunLoop
Instanz pro gibtNSThread
undNSRunLoop
genau die antreibtNSThread
, können wir berücksichtigen, dass Zugriffe von derselbenNSRunLoop
Instanz immer niemals Threads kreuzen.Basierend auf den zuvor genannten Punkten können wir jetzt den Code schreiben: einen NSRunLoop-basierten Task-Dispatcher:
Mit dem vorherigen Code können wir nun die Ausführung von
UICollectionView
'sreloadData()
durch einen solchen Code an das Ende der aktuellen Ereignisschleife senden:Tatsächlich befand sich ein solcher NSRunLoop-basierter Task-Dispatcher bereits in einem meiner persönlich verwendeten Frameworks: Nest. Und hier ist das Repository auf GitHub: https://github.com/WeZZard/Nest
quelle
es hat bei mir funktioniert.
quelle
Vielen Dank zunächst für diesen Thread, sehr hilfreich. Ich hatte ein ähnliches Problem mit Reload Data, außer dass das Symptom war, dass bestimmte Zellen nicht mehr dauerhaft ausgewählt werden konnten, während andere dies konnten. Kein Aufruf der indexPathsForSelectedItems-Methode oder einer gleichwertigen Methode. Beim Debuggen wurde darauf hingewiesen, Daten neu zu laden. Ich habe beide Optionen oben ausprobiert. Am Ende wurde die Option ReloadItemsAtIndexPaths übernommen, da die anderen Optionen in meinem Fall nicht funktionierten oder die Sammlungsansicht etwa eine Millisekunde lang blinken ließen. Der folgende Code funktioniert gut:
quelle
Es passierte auch bei mir in iOS 8.1 sdk, aber ich habe es richtig verstanden, als ich bemerkte, dass
datasource
die Methode auch nach dem Aktualisieren der MethodenumberOfItemsInSection:
nicht die neue Anzahl von Elementen zurückgab. Ich habe die Zählung aktualisiert und zum Laufen gebracht.quelle
Legen Sie UICollectionView.contentInset fest? entferne den linken und rechten RandInset, alles ist in Ordnung, nachdem ich sie entfernt habe, der Fehler existiert immer noch in iOS8.3.
quelle
Überprüfen Sie, ob jede der UICollectionView Delegate-Methoden das tut, was Sie von ihr erwarten. Zum Beispiel, wenn
gibt keine gültige Größe zurück, das Nachladen funktioniert nicht ...
quelle
Versuchen Sie diesen Code.
quelle
So hat es bei mir in Swift 4 funktioniert
quelle
quelle