Muszę wykonać jakąś operację za każdym razem, gdy UICollectionView został całkowicie załadowany, tj. W tym czasie należy wywołać wszystkie metody źródła danych / układu UICollectionView. Skąd mam to wiedzieć? Czy istnieje metoda delegata, aby poznać stan załadowania UICollectionView?
uicollectionview
delegates
reload
Jirune
źródło
źródło
[self.collectionView removeObserver:self forKeyPath:@"contentSize" context:NULL];
do-viewWillDisappear:animated:
.To zadziałało dla mnie:
Składnia Swift 4:
źródło
reloadData
odświeża,collectionView
więc ponownie rysuje na swoich metodach źródła danych ...performBatchUpdates
ma dołączony blok uzupełniania, więc jeśli oba są wykonywane w głównym wątku, znasz dowolny kod, który wstawiony w miejsce/// collection-view finished reload
will, zostanie wykonany z nowym i ułożonymcollectionView
W rzeczywistości jest to raczej bardzo proste.
Gdy na przykład wywołujesz metodę reloadData UICollectionView lub metodę invalidateLayout układu, wykonaj następujące czynności:
Dlaczego to działa:
Główny wątek (w którym powinniśmy robić wszystkie aktualizacje interfejsu użytkownika) zawiera kolejkę główną, która ma charakter seryjny, czyli działa w stylu FIFO. W powyższym przykładzie zostaje wywołany pierwszy blok, który wywołuje naszą
reloadData
metodę, a następnie cokolwiek innego w drugim bloku.Teraz główny wątek również się blokuje. Więc jeśli
reloadData
wykonanie zajmuje 3 sekundy, przetwarzanie drugiego bloku zostanie odroczone o te 3 sekundy.źródło
reloadData
teraz kolejkuje ładowanie komórek w głównym wątku (nawet jeśli są wywoływane z głównego wątku). Więc komórki nie są faktycznie ładowane (cellForRowAtIndexPath:
nie są wywoływane) poreloadData
powrocie. Zawijanie kodu, który chcesz wykonać po załadowaniu komórek,dispatch_async(dispatch_get_main...
i wywołanie go po wywołaniureloadData
przyniesie pożądany rezultat.Aby dodać do świetnej odpowiedzi @dezinezync:
Swift 3+
źródło
Zrób to tak:
źródło
Spróbuj wymusić synchroniczne przekazywanie układu za pomocą layoutIfNeeded () zaraz po wywołaniu reloadData (). Wydaje się, że działa zarówno dla UICollectionView, jak i UITableView w systemie iOS 12.
źródło
Jak odpowiedział dezinezync , wystarczy wysłać do kolejki głównej blok kodu po
reloadData
zUITableView
lubUICollectionView
i wtedy ten blok zostanie wykonany po dekolejkowaniu komórekAby było to prostsze podczas używania, użyłbym takiego rozszerzenia:
Może być również realizowane Do
UITableView
takżeźródło
Inne podejście przy użyciu RxSwift / RxCocoa:
źródło
performBatchUpdates
nie działał w moim przypadku, ten to robi. Twoje zdrowie!To działa dla mnie:
źródło
Musiałem wykonać jakąś akcję na wszystkich widocznych komórkach, gdy widok kolekcji zostanie załadowany, zanim będzie widoczny dla użytkownika, użyłem:
Zwróć uwagę, że zostanie to wywołane podczas przewijania widoku kolekcji, więc aby temu zapobiec, dodałem:
aw samej akcji:
Akcja będzie nadal wykonywana wiele razy, ponieważ liczba widocznych komórek w stanie początkowym. ale we wszystkich tych wywołaniach będziesz mieć taką samą liczbę widocznych komórek (wszystkie). A flaga logiczna uniemożliwi ponowne uruchomienie po rozpoczęciu interakcji użytkownika z widokiem kolekcji.
źródło
Wykonałem następujące czynności, aby wykonać cokolwiek po ponownym załadowaniu widoku kolekcji. Możesz użyć tego kodu nawet w odpowiedzi API.
źródło
Najlepszym rozwiązaniem, jakie do tej pory znalazłem, jest
CATransaction
obsługa kompletacji.Swift 5 :
źródło
Def zrób to:
Następnie zadzwoń w ten sposób w swoim VC
Upewnij się, że używasz podklasy !!
źródło
Ta praca dla mnie:
źródło
Po prostu przeładuj kolekcję Wyświetl aktualizacje wsadowe, a następnie sprawdź w bloku uzupełniania, czy zostało to zakończone, czy nie, za pomocą boolowskiego „finish”.
źródło
Poniżej znajduje się jedyne podejście, które zadziałało dla mnie.
źródło
Oto jak rozwiązałem problem ze Swift 3.0:
źródło
Spróbuj tego:
źródło
Możesz to zrobić ...
źródło