2012-09-30 16 views
19

Zauważyłem, że podczas wywoływania setLayout:animated w UICollectionView aby przełączyć się pomiędzy dwoma układami, aktualnie widoczne komórka nie przylegają do zIndex to atrybuty układ został ustawiony w layoutAttributesForItemAtIndexPath:.UICollectionView setLayout: animowane: nie zachowując zindex

Na przykład, jeśli były mieć UICollectionView z UICollectionViewFlowLayout ustawić to minimumLineSpacing na ujemną więc komórki pokrywają się, a następnie ustawić zIndex każdej komórce wyższego niż w poprzedniej komórki, to wydaje się, czy komórki są układane od dołu do góry.

To jednak zepsuje się, jeśli ustawię układ na inny układ, a następnie powrócę do oryginalnego układu. To tak, jakby aktualnie widoczna komórka nie słuchała zIndex i została umieszczona na pozostałych komórkach. Jeśli przewińę komórkę poza ekran, a następnie ponownie, to jest we właściwym miejscu.

Odpowiedz

1

spróbuj ustawić z-index w:

- (UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath; 
- (UICollectionViewLayoutAttributes *)finalLayoutAttributesForDisappearingItemAtIndexPath:(NSIndexPath *)itemIndexPath; 
+0

Dzięki za odpowiedź, chociaż nie miałem szczęścia w rozwiązaniu. Myślę, że problem polega na tym, że UICollectionView robi coś z zIndexem wybranej komórki. Mogę się mylić, ale zmiana układu nie może wywołać "initialLayoutAttributesForAppearingItemAtIndex", jeśli komórka jest już widoczna i pozostaje widoczna podczas zmiany układu. – sampage

+0

Właśnie podałem krótki przykład tego i byłem w stanie odtworzyć problemy z Z-Index. Rozumiem, że 'initialLayoutAttributesForAppearingItemAtIndex' został wywołany dla każdego elementu na ekranie po unieważnieniu (zmiana animowanych granic, blok aktualizacji partii), ale po ponownym przeczytaniu dokumentów dotyczy tych elementów, które wymagają animacji. Na szczęście udało mi się uzyskać niezmienne wyniki przy przełączaniu układów, ustawiając indeks z w "layoutAttributesForElementsInRect:' zamiast 'layoutAttributesForItemAtIndexPath:' –

+0

@sampage czy możesz mi powiedzieć więcej o indeksie z wybranych komórek? Nie mogę znaleźć nigdzie dowodu na to, co mówisz, ale dostrzegam pewne niekonsekwencje w moich animacjach ... Dzięki! –

10

miałem ten sam problem. Przełączenie układu spowoduje zignorowanie zIndex dla komórki.

udało mi się zrobić to „dobrze wyglądać” stosując tłumaczenie na osi jak ten:

attributes.transform3D = CATransform3DMakeTranslation(0, 0, indexPath.row); 

Ale to tylko wizualny fix, jeśli spróbujesz kliknąć na element, który zorientuje się, że zIndex jest nadal nieprawidłowy, dopóki nie zostanie poddany recyklingowi, przewijając go poza ekranem.

+0

Jeśli twoja odpowiedź nie jest rzeczywistym rozwiązaniem, proponuję opublikować ją jako komentarz. –

+0

Niestety, nie znam się na etykiecie Stack Overflow. Nie jestem pewien, jak opublikować komentarz, ale wszystko, co mogę znaleźć, to "Dodaj kolejną odpowiedź". – TheoB

+0

Masz całkowitą rację: [dodanie komentarza] (http://stackoverflow.com/privileges/comment) wymaga 50 punktów reputacji. Nie chciałem cię popychać. Współpraca jest mile widziana. Mój komentarz jest zaproszeniem do współpracy w ramach SO. :) –

8

Udało mi się uzyskać pożądane zachowanie, używając kombinacji grimfrog i odpowiedzi Charliego Elliotta.

Rozwiązanie Charliego Elliotta otrzymało prawidłowy wynik końcowy dla elementów w widoku kolekcji, ale podczas animacji nadal występował efekt przyciągania do obiektu zIndex.

Rozwiązanie Grimfroga zapewniało poprawny wygląd, ale problem zIndexu nadal był nieprawidłowy po zmianie układu, mimo że wyglądał prawidłowo.

Kombinacja dwóch, podczas gdy nie jest to świetne rozwiązanie, działa i używa obsługiwanych transformacji i właściwości zindex tych UICollectionViewLayoutAttributes

W moim układzie, mam

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect 
{ 
    NSArray *attributes = [super layoutAttributesForElementsInRect:rect]; 

    [attributes enumerateObjectsUsingBlock:^(UICollectionViewLayoutAttributes *attributes, NSUInteger idx, BOOL *stop) { 
    attributes.zIndex = attributes.indexPath.item + 1; 
    }]; 

    return attributes; 
} 

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath 
{ 
    UICollectionViewLayoutAttributes *attributes = [super layoutAttributesForItemAtIndexPath:indexPath]; 

    attributes.transform3D = CATransform3DMakeTranslation(0, 0, attributes.indexPath.item); 
    return attributes; 
} 

Wygrałem” t to właśnie jest poprawna odpowiedź, ponieważ jestem pewien, że musi być inny sposób rozwiązania tego problemu, ale jestem zainteresowany, czy to rozwiąże problem także dla innych.

+0

To działa dla mnie, ale nie jestem pewien, dlaczego transform3D musi być ustawiony w layoutAttributesForItemAtIndexPath. Nie działa, jeśli jest ustawiony tylko w layoutAttributesForElementsInRect. – honcheng

3

Ten kawałek mnie też. Po kilku testach zdałem sobie sprawę, że UICollectionView wymusi na górze wybrane komórki, niezależnie od indeksu Z.

0

Korzystanie @sampage & odpowiedzi @grimfrog jako punkt wyjścia, udało mi się dostać podobną sytuację roboczą

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)path 
{ 
    UICollectionViewLayoutAttributes* attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:path]; 
    attributes.zIndex = path.item; 
    attributes.transform3D = CATransform3DMakeTranslation(0, 0, path.item); 
    // other attribute settings 
    return attributes; 
} 

Moje layoutAttributesForElementsInRect: połączeń layoutAttributesForItemAtIndexPath: podczas generowania tablicę atrybutów - więc tylko potrzebne do włączenia zindex i przekształć tam.

6

Spróbuj:

// In UICollectionViewCell subclass 
- (void)applyLayoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes 
{ 
    [super applyLayoutAttributes:layoutAttributes]; 
    // Setting zPosition instead of relaying on 
    // UICollectionView zIndex management 'fixes' the issue 
    self.layer.zPosition = layoutAttributes.zIndex; 
} 
+0

Działa urok, dzięki. –

0

mam innego obejścia. Ponieważ wszystkie komórki należą do tego samego superview, wywołując bringSubviewToFront :, gdy działa wyświetlanie komórek. W szczególności, patrząc na hierarchię widoku debugowania, mimo że UICollectionViewLayout nie renderuje komórek zgodnie z zIndex, nadal wyświetla komórki zgodnie z kolejnością w odwrotnej kolejności, w której każdy podzbiór jest dodawany do super widoku.

Powiązane problemy