uicollectionviewcontroller ios objective-c uikit core-animation uicollectionview

ios - uicollectionviewcontroller - UICollectionVIew: animar celdas a medida que se desplazan en



uicollectionviewcell indexpath (3)

Me gustaría que los elementos de mi UICollectionView animaran para verlos mientras el usuario se desplaza por la lista (estoy usando una subclase de UICollectionViewFlowLayout ).

Especifico la posición en el Administrador de diseño, lo que me gustaría poder hacer es especificar también una transformación inicial y aplicarla en una animación en el momento correcto (cuando la celda aparece por primera vez en la pantalla). Para ver el efecto que quiero decir, echa un vistazo a la aplicación Google Plus en iOS. Idealmente una transformación diferente dependiendo de la ubicación de la celda.

Parece que no puedo encontrar una manera de averiguar cuándo se muestra una celda (no hay un equivalente de willDisplayCell como la que se encuentra en UITableView ) o cualquier indicador sobre dónde ir para esto.

¿Alguna sugerencia?

Usted puede casi hacer la animación en Google Plus en esta captura de pantalla:

Además, echa un vistazo a iPhoto en el iPad. No sé si están usando un UIcollectionView (probablemente no, como funcionó en iOS5) pero este es el tipo de efecto que estoy buscando, las fotos parecen volar desde la derecha.


Como Marc mencionó en un comentario, que terminó usando una vista de desplazamiento, quiero mostrar cómo hacerlo con una vista de tabla estándar. No es el mismo efecto que se ve en google + pero se puede adaptar fácilmente.

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { static CGFloat duration = .5; static NSUInteger xOffset = 50; static NSUInteger yOffset = 200; if(scrollDirection == STAScrollDirectionDown && lastAnimatedIndex < indexPath.row) { cell.frame = CGRectMake(cell.frame.origin.x - xOffset, cell.frame.origin.y+yOffset, cell.frame.size.width, cell.frame.size.height); [UIView animateWithDuration:duration animations:^{ cell.frame = CGRectMake(cell.frame.origin.x + xOffset, cell.frame.origin.y - yOffset, cell.frame.size.width, cell.frame.size.height); } completion:^(BOOL finished) { lastAnimatedIndex = indexPath.row; }]; } }

Justo antes de que se muestre la celda, asignamos un desplazamiento (y posiblemente una rotación) a cada celda y luego lo animamos a la configuración anterior.

Un ejemplo un poco más emocionante:

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { CATransform3D rotation = CATransform3DMakeRotation( (90.0*M_PI)/180, .0, 0.5, 0.5); cell.contentView.alpha = 0.8; cell.contentView.layer.transform = rotation; cell.contentView.layer.anchorPoint = CGPointMake(0, 0.5); [UIView animateWithDuration:.5 animations:^{ cell.contentView.layer.transform = CATransform3DIdentity; cell.contentView.alpha = 1; cell.contentView.layer.shadowOffset = CGSizeMake(0, 0); } completion:^(BOOL finished) { }]; }


Puede lograr este efecto independientemente de tener un diseño personalizado.

El código de animación debe ir dentro de collectionView:cellForItemAtIndexPath:

Cuando una celda se deja en cola, su frame se establecerá en lo que se especifica en su diseño. Puede almacenarlo en una variable temporal como el frame final para la celda. A continuación, puede establecer el cell.frame en una posición inicial fuera de la pantalla, y luego animar hacia la posición final deseada. Algo a lo largo de las líneas de:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { UICollectionView *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath]; CGRect finalCellFrame = cell.frame; //check the scrolling direction to verify from which side of the screen the cell should come. CGPoint translation = [collectionView.panGestureRecognizer translationInView:collectionView.superview]; if (translation.x > 0) { cell.frame = CGRectMake(finalCellFrame.origin.x - 1000, - 500.0f, 0, 0); } else { cell.frame = CGRectMake(finalCellFrame.origin.x + 1000, - 500.0f, 0, 0); } [UIView animateWithDuration:0.5f animations:^(void){ cell.frame = finalCellFrame; }]; return cell; }

El código anterior animará las celdas en un UICollectionView horizontal, proveniente de la parte superior de la pantalla, y desde cualquier lado, dependiendo de la dirección de desplazamiento. También puede verificar la indexPath actual para que las celdas se indexPath desde diferentes posiciones en diseños más complicados, así como animar otras propiedades junto con el marco, o aplicar una transformación.


initialLayoutAttributesForAppearingItemAtIndexPath: anular initialLayoutAttributesForAppearingItemAtIndexPath: en el diseño de la vista de colección. Aquí puede establecer cualquier atributo en el elemento de atributos de diseño (incluida la transformación) que se animará a los atributos reales una vez que haya aparecido la celda.

Si el objeto de atributos de diseño estándar no le brinda suficientes opciones, puede applyLayoutAttributes: subclase, agregar atributos adicionales y anular applyLayoutAttributes: en su celda para seleccionar las propiedades adicionales.

Esto solo funcionará cuando agregue celdas a la vista de colección.

Para que las transformaciones se apliquen a las celdas a medida que se desplaza hacia abajo en la vista de colección, vería aplicarlas directamente a la celda (en cellForItem ...) o en los atributos de diseño, tal vez una propiedad llamada initialTransform . Al aplicar los atributos de diseño a la celda, verificará la initialTransform , la aplicará y luego la configurará en identidad, luego activará una animación para ir a la transformación de identidad, por lo que solo se aplicaría cuando la celda se desplazó por primera vez a la celda. pantalla. No he implementado nada como esto, es solo una suposición de cómo lo haría.