2012-09-30 61 views
19

me he dado cuenta que cuando se llama a setLayout:animated en un UICollectionView para cambiar entre dos diseños, la célula visible en ese momento no se adhiere a la zIndex sus atributos de diseño se ha puesto en layoutAttributesForItemAtIndexPath:.UICollectionView setLayout: animado: no preservar zIndex

Por ejemplo, si tuviera que tener un UICollectionView con UICollectionViewFlowLayout, ajuste que es minimumLineSpacing a un número negativo de modo que las células se superponen y luego ponga un zIndex en cada celda mayor que la de la celda anterior, a continuación, aparece como si el las células se apilan desde abajo hacia arriba.

Sin embargo, esto se rompe si establezco el diseño en otro diseño y vuelvo a ese diseño original. Es como si la celda visible actualmente no escuchara zIndex y se coloca encima de las otras celdas. Si desplazo la celda fuera de la pantalla, vuelva a colocarla en el lugar correcto.

Respuesta

1

establecer el índice z en Probar:

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

Gracias por la respuesta, aunque no he tenido suerte con su solución. Creo que el problema es que UICollectionView hace algo con el zIndex de la celda seleccionada. Puedo estar equivocado, pero cambiar el diseño puede no llamar al '' initialLayoutAttributesForAppearingItemAtIndex'' si la celda ya está visible y permanece visible durante todo el cambio de diseño. – sampage

+0

Acabo de elaborar un ejemplo rápido de esto y pude reproducir los problemas con el Z-Index. Comprendí que se llamó a 'initialLayoutAttributesForAppearingItemAtIndex' para cada elemento en la pantalla después de la invalidación (cambio de límites animados, bloque de actualización por lotes), pero después de volver a leer los documentos, es para los elementos que necesitan animación. Afortunadamente, pude obtener resultados consistentes al cambiar diseños al configurar el índice z en 'layoutAttributesForElementsInRect:' en lugar de 'layoutAttributesForItemAtIndexPath:' –

+0

@sampage ¿me puede decir algo más sobre el índice Z de las celdas seleccionadas? No puedo encontrar ninguna prueba de lo que dices, pero veo algunas inconsistencias en mis animaciones ... ¡Gracias! –

10

he tenido el mismo problema. Cambiar el diseño ignorará el zIndex para la celda.

que han logrado hacer que "se ve bien" mediante la aplicación de traducción en el eje z como esto:

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

Pero es sólo una solución visual, si intenta hacer clic en el elemento que se dará cuenta de que zIndex sigue siendo incorrecto hasta que se recicla desplazándolo fuera de la pantalla.

+0

Si su respuesta no es la real, le sugiero que la publique como comentario. –

+0

Lo siento, no estoy familiarizado con la etiqueta de desbordamiento de pila. Aunque no estoy seguro de cómo publicar un comentario, todo lo que puedo encontrar es 'Agregar otra respuesta'. – TheoB

+0

Tiene toda la razón: [agregar un comentario] (http://stackoverflow.com/privileges/comment) requiere 50 puntos de reputación. No quise extenderte. Colaborar es bienvenido. Mi comentario es una invitación a colaborar de la manera SO. :) –

8

He logrado obtener el comportamiento que busco mediante el uso de una combinación de Grimfrog y las respuestas de Charlie Elliott.

La solución de Charlie Elliott obtuvo el resultado final correcto para los elementos en la vista de colección, pero todavía había un efecto de ajuste en el índice z durante la animación.

La solución de grimfrog proporcionó el aspecto correcto pero tuvo el problema de que el zIndex sigue siendo incorrecto después del cambio de diseño, a pesar de parecer correcto.

La combinación de los dos, aunque no es una gran solución, funciona y que utilizan la apoyaron transformar y propiedades zIndex de los UICollectionViewLayoutAttributes

En mi diseño, tengo

- (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; 
} 

gané' Creo que esta es la respuesta correcta ya que estoy seguro de que debe haber otra forma de resolver esto, pero me interesa ver si esto resuelve el problema para otros también.

+0

Esto funciona para mí, pero no estoy seguro de por qué transform3D tiene que establecerse en layoutAttributesForItemAtIndexPath. No funciona si solo está configurado en layoutAttributesForElementsInRect. – honcheng

3

Esto también me mordió. Después de varias pruebas, me di cuenta de que UICollectionView obligará a las celdas seleccionadas a estar en la parte superior, independientemente del índice z.

0

Usando @sampage & @grimfrog respuestas como punto de partida, yo era capaz de conseguir una situación similar a trabajar

- (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; 
} 

Mis layoutAttributesForElementsInRect: llamadas layoutAttributesForItemAtIndexPath: al generar la matriz de atributos - por lo que sólo necesitaba para incluir el zIndex y transform3D allí.

6

Probar:

// 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

Funciona un encanto, gracias. –

0

tengo otra solución. Dado que todas las celdas pertenecen a la misma supervista, llame al bringSubviewToFront : cuando la celda funcione. Específicamente, al examinar la jerarquía de vistas de depuración, aunque UICollectionViewLayout no muestra las celdas de acuerdo con zIndex, todavía muestra las celdas según el orden inverso en que cada subvista se agrega a su supervista.

Cuestiones relacionadas