Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

637
Vistas
El encabezado fijo de UICollectionView desaparece durante un tiempo después de insertar la sección cuando la colección se desplaza demasiado (efecto de rebote)

Estoy usando UICollectionReusableView como encabezado de la sección UICollectionView . Habilité "encabezados fijos" con:

 let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout layout?.sectionHeadersPinToVisibleBounds = true

Estoy insertando nuevas secciones a la colección con:

 collectionView.performBatchUpdates({ self.collectionView.insertSections(IndexSet(integersIn: collectionView.numberOfSections...viewModel.numberOfSections - 1)) }, completion: nil)

Si la inserción ocurre cuando la colección se desplaza demasiado (el rebote está habilitado), el encabezado desaparecerá por un tiempo (vea el GIF a continuación). ¿Cómo puedo evitar este comportamiento?

Estoy usando iOS 12.1.4, pero también ocurre el mismo problema en los simuladores de iOS 11.x y 12.x.

El problema no ocurre si el efecto de rebote está desactivado, pero quiero mantenerlo activado para una sensación de desplazamiento más suave. Intenté invalidar el diseño antes/después de la actualización sin resultado. Gracias por los consejos.

ingrese la descripción de la imagen aquí

EDITAR (26/02/2019)
Solución alternativa: envolver la inserción para performWithoutAnimation bloque de ejecución sin animación, resolver la desaparición del encabezado pero, obviamente, deshabilitar la animación de recarga.

 UIView.performWithoutAnimation { collectionView.performBatchUpdates({ self.collectionView.insertSections(IndexSet(integersIn: collectionView.numberOfSections...viewModel.numberOfSections - 1)) }, completion: nil) }
over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Desafortunadamente, al llamar a performBatchUpdates, el diseño anima automáticamente todos los elementos. Incluso hasta ahora, no hay forma de decir explícitamente qué elementos animar y cuáles no.

Sin embargo, se me ocurrió una resolución que es una especie de antipatrón.

Para su clase de encabezado, anule estos métodos:

 -(void)setBounds:(CGRect)bounds { [CATransaction begin]; [CATransaction setDisableActions:self.shouldDisableAnimations]; [super setBounds:bounds]; [CATransaction commit]; } //-(void)setCenter:(CGPoint)center - (void)setCenter:(CGPoint)center { [CATransaction begin]; [CATransaction setDisableActions:self.shouldDisableAnimations]; [super setCenter:center]; [CATransaction commit]; }

Ahora, si shouldDisableAnimations es verdadero, las animaciones automáticas de collectionView no se aplicarán a nuestro encabezado.

Sin embargo, deshabilitar las animaciones para el encabezado puede causar otras fallas (por ejemplo, cuando se desplaza mucho hacia abajo y luego elimina todas las celdas, el encabezado saltará a la parte superior instantáneamente y la vista de colección se desplazará hacia arriba con una animación que resultará en una falla).

Para manejar esto, debemos configurar shouldDisableAnimations para el encabezado en el momento correcto, que es cuando se llama a prepareForCollectionViewUpdates. Desafortunadamente, no podemos hacer esto a través del atributo del encabezado ya que los atributos se aplican al encabezado después de que finaliza la animación. Por lo tanto, debemos acceder directamente a la instancia del encabezado directamente desde el método prepareForCollectionViewUpdates. (Hay varias formas de hacer esto. Lo hice manteniendo una referencia débil del encabezado en una propiedad de clase de sí mismo)

 -(void)prepareForCollectionViewUpdates:(NSArray<UICollectionViewUpdateItem *> *)updateItems { // Keep track of insert and delete index paths [super prepareForCollectionViewUpdates:updateItems]; [self.indexPaths2Delete removeAllObjects]; [self.indexPaths2Insert removeAllObjects]; for (UICollectionViewUpdateItem *update in updateItems) { if (update.updateAction == UICollectionUpdateActionDelete) { [self.indexPaths2Delete addObject:update.indexPathBeforeUpdate]; } else if (update.updateAction == UICollectionUpdateActionInsert) { [self.indexPaths2Insert addObject:update.indexPathAfterUpdate]; } } if (self.indexPaths2Insert.count > 0 || self.indexPaths2Delete.count > 0) { HomeHeaderView.liveInstance.shouldDisableAnimations = false; //since it may cause scrolling, we should enable the animations } else HomeHeaderView.liveInstance.shouldDisableAnimations = true; //there's nothing added or deleted, so keep the header sticked. }

over 4 years ago · Santiago Trujillo Denunciar

0

La solución anterior que proporcioné anteriormente parece no funcionar en iOS 13.

Durante performBatchUpdates, UICollectionView no aplica atributos de diseño para los elementos. La única forma de solucionar esto es configurar el marco (o cualquier otro parámetro) en el encabezado explícitamente desde el método prepare() del diseño. Debido a que se está realizando una animación en curso, UICollectionView no se distribuirá durante la animación.

Creo que Apple tiene que agregar una función para marcar explícitamente qué elementos participan en la animación y cuáles no. Esto se puede hacer a través de los atributos de diseño de los elementos o un método separado en UICollectionViewLayout.

¡Acceder a las instancias de elementos desde el diseño es un no-no! Pero no hay otras soluciones en este momento.

over 4 years ago · Santiago Trujillo Denunciar

0

También estaba teniendo el mismo problema, pero el trabajo que he hecho es volver a cargar el collectionView (el encabezado fijo no desapareció) en lugar de insertarlo.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda