Podczas wstawiania wielu niestandardowych widoków dodatkowych w widoku kolekcji z istniejącymi dodatkowymi widokami, przy użyciu podklasy UICollectionViewFlowLayout, widok kolekcji wydaje się tworzyć animacje z załamaniem lub w inny sposób nie obsługuje poprawnie wstawień.Usterka animacji układu podczas wstawiania wielu niestandardowych widoków dodatkowych
Wstawianie jednego dodatkowego widoku zachowuje się zgodnie z oczekiwaniami, ale wstawienie dwóch dodatkowych widoków od razu powoduje oczywisty błąd wizualny, a wstawienie wielu dodatkowych widoków jednocześnie (na przykład 4+) pogarsza błąd. (10.2 iOS, iOS 9.3, Swift 3, Xcode 8.2.1)
Oto demonstracji:
można odtworzyć problem za pomocą this sample project. W tym uproszczonym przykładzie istnieje jeden dodatkowy widok dla każdej pozycji, a dwie pozycje (z dwoma dodatkowymi widokami) są wstawiane podczas każdej aktualizacji partii. W moim prawdziwym projekcie mam mniej widoków dodatkowych niż elementów i korzystam z innych funkcji układu przepływu.
Moje najlepsze przypuszczenie jest takie, że coś powoduje widok kolekcji w celu wprowadzenia w błąd ścieżek indeksu lub atrybutów układu odpowiadających istniejącym/wstawionym dodatkowym widokom. Jeśli okaże się, że jest to błąd w jednej z klas Apple'a, byłbym bardzo wdzięczny za twoje najbardziej eleganckie obejście.
usiłowania rozwiązania
Próbowałem i dwukrotnie sprawdzane każdy z następujących czynności:
Wdrażanie
indexPathsToInsertForSupplementaryView(ofKind:)
-tak ile mogę powiedzieć, to jest proste i moja implementacja zwraca poprawne ścieżki indeksu. Widoki są zawsze wstawiane. W przypadku dodatkowych widoków nagłówka i stopki wydaje się, że UICollectionViewFlowLayout zwraca uporządkowaną tablicę ścieżek indeksu, ale sortowanie tablicy nie ma dla mnie żadnej różnicy.Zapewnienie układ początkowy i końcowy atrybuty -calling
super
dla tych metod wydaje się powrót poprawnych ramek, więc to nie jest oczywiste, co korekty (jeśli w ogóle) może być wykonana z układem początkowym lub końcowym atrybuty, aby rozwiązać problem. Ale zobacz trzecią ciekawość zanotowaną poniżej.Unieważnienie układ -to wydaje się mieć żadnego znaczenia w ogóle, czy układ jest ręcznie unieważniony w całości lub w części przed, w trakcie lub po
performBatchUpdates()
, albo w ogóle.niestandardowe ścieżki indeksowe -Mimo ścieżki indeksu dla elementów uzupełniających nie muszą odpowiadać ścieżek indeks towaru, o ile mogę powiedzieć, a mimo dokumentacji przeciwnego UICollectionViewFlowLayout padnie (poprzez zwrócenie się do atrybutów układ nieistniejące ścieżki indeksu), chyba że dodatkowe elementy tego samego rodzaju są ponumerowane kolejno od 0. Zakładam, że w ten sposób widok kolekcji i/lub obiekt układu jest w stanie obliczyć nowe ścieżki indeksu po wstawieniu lub usunięciu elementów (np. lub dekrementowanie właściwości ścieżki indeksu). Zatem tworzenie dowolnych ścieżek indeksu nie jest opcją.
Ciekawostki zauważył podczas debugowania
usterki wizualne są specyficzne dla dodatkowych poglądów i nie występują na wstawianych elementów, nawet gdy ścieżki i ramki indeksu są takie same dla obu stron.
Po debugowaniu hierarchii widoków okazuje się, że ramki wstawionych widoków dodatkowych są poprawne, ale ramki niektórych istniejących widoków dodatkowych nie są poprawne. Dzieje się tak pomimo faktu, że ramki zwrócone przez obiekt układu dla istniejących widoków na tych ścieżkach indeksu wydają się poprawne.
Podczas wstawiania wielu dodatkowych widoków połączenia wykonane przez widok kolekcji dla początkowych i końcowych atrybutów układu wydają się być niezbalansowane. Oznacza to, że początkowe atrybuty układu są wymagane wiele razy dla tej samej ścieżki indeksu (i, naturalnie, te same atrybuty są zwracane za każdym razem), a liczba zaproszeń do ostatecznych atrybutów układu jest mniejsza. Co więcej, w przypadku niektórych istniejących widoków dodatkowych początkowe i końcowe atrybuty układu nigdy nie są wymagane. Uważam to za podejrzane. Prowadzi mnie to do przekonania, że widok kolekcji jest mylący z dodatkowymi widokami i/lub ścieżkami indeksu przed aktualizacją i po niej.
Adresy pamięci dla instancji IndexPath utworzonej przez mój kod Swift są uderzająco różne od instancji NSIndexPath utworzonej wewnętrznie przez UICollectionView i UICollectionViewFlowLayout. Te pierwsze są zawsze różne (zgodnie z oczekiwaniami), podczas gdy te drugie wydają się identyczne między uruchomieniami (np. [0, 0], [0, 1] i [0, 2] są zawsze pod
0xc000000000000016
,0xc000000000200016
i0xc000000000400016
). W Swift, IndexPath jest zmostkowany do NSIndexPath, ale the former is a value type whereas the latter is a reference type. NSIndexPath również uses tagged pointers. Istnieje odległa możliwość, że oba zostały niedokładnie zmostkowane i/lub że klasy widoku kolekcji polegają wewnętrznie na zachowaniu NSIndexPath w pewien sposób, który powoduje tutaj widoczne zamieszanie ścieżki indeksu. Nie wiem, jak to przetestować lub zrobić to dalej.
Podobne pytania
Poniższe pytania mogą być związane, chociaż żadna z odpowiedzi pracował dla mnie:
How can UICollectionView supplementary views be inserted or deleted correctly
layoutAttributesForSupplementaryViewOfKind:atIndexPath: passes in incorrect indexPath
UICollectionView supplementary views won't animate “in” or “out”
UICollectionView Decoration and Supplementary views can not be moved
Problem może być również związane z this bug report na Open Radar. Przykładowy projekt towarzyszący temu sprawozdaniu jest nieco zbyt skomplikowany, aby mógł być przydatny.
Pomoc techniczna firmy Apple
Po wysłaniu na to pytanie, ja przedstawiła pomocy technicznej incydent Apple.Dział wsparcia dla programistów Apple odpowiedział w następujący sposób:
Nasi inżynierowie sprawdzili Twoją prośbę i stwierdzili, że najlepiej będzie, gdy zostanie to potraktowane jako zgłoszenie błędu.
Prześlij pełny raport o błędzie dotyczący tego problemu, korzystając z narzędzia do zgłaszania błędów pod numerem https://developer.apple.com/bug-reporting/.
...
Spędziliśmy trochę czasu na zbadanie możliwości obejścia i niestety mają pochodzić z pustymi rękami. Proszę uzupełnij swój błąd. Jeśli odkryjemy możliwość obejścia tego problemu w przyszłości, wyciągniemy rękę. Przepraszam, nie mam lepszych wiadomości.
Jeśli wystąpi ten problem, należy zduplikować numer rdar://30510010.
Wygląda na to, że jest to jeden z błędów UICollectionView. –
Spróbuj użyć zależności blokowych (implementacja obietnic) z biblioteki Śruby, aby powiązać jedną wstawkę z kolejną. Powinno to zapobiec jednoczesnemu wprowadzeniu usterki i wyglądać bardziej naturalnie. – jarryd