Permitir una vista de encabezado para solo ciertas secciones usando una UICollectionView de iOS
objective-c uicollectionreusableview (5)
**
Si devuelve un valor de tamaño (0, 0), no se agrega ningún encabezado.
**
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
switch section {
case 0:
return CGSize(width: collectionView.bounds.width, height: 70)
case 1:
return CGSize(width: 0, height: 0) // NO HEADER WILL BE ADDED
case 2:
return CGSize(width: collectionView.bounds.width, height: 70)
case 3:
return CGSize(width: 0, height: 0) // NO HEADER WILL BE ADDED
default:
return CGSize(width: collectionView.bounds.width, height: 70)
}
}
El siguiente código muestra mi vista de encabezado correctamente, pero para cada una de las secciones en UICollectionView:
-(UICollectionReusableView *)collectionView:(UICollectionView *)collectionView
viewForSupplementaryElementOfKind:(NSString *)kind
atIndexPath:(NSIndexPath *)indexPath {
UICollectionReusableView * headerView =
[collectionView
dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader
withReuseIdentifier:@"SectionHeaderCollectionReusableView"
forIndexPath:indexPath];
switch (indexPath.section) {
case Section_One:
return headerView;
case Section_Two:
return headerView;
case Section_Three:
return headerView;
case Section_Four:
return headerView;
case Section_Five:
return headerView;
default:
return headerView;
}
}
Lo que me gustaría hacer en su lugar, no es mostrar una vista de encabezado para ''Section_One'' o ''Section_Two'', pero devolver ''nil'' resulta en una ''NSInternalInconsistencyException'':
-(UICollectionReusableView *)collectionView:(UICollectionView *)collectionView
viewForSupplementaryElementOfKind:(NSString *)kind
atIndexPath:(NSIndexPath *)indexPath {
UICollectionReusableView * headerView =
[collectionView
dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader
withReuseIdentifier:@"SectionHeaderCollectionReusableView"
forIndexPath:indexPath];
switch (indexPath.section) {
case Section_One:
return nil;
case Section_Two:
return nil;
case Section_Three:
return headerView;
case Section_Four:
return headerView;
case Section_Five:
return headerView;
default:
return nil;
}
}
¿Qué necesito hacer para mostrar una vista de encabezado solo para ciertas secciones?
Continúe y devuelva un encabezado para cada sección y luego configure el tamaño del encabezado de la sección para que tenga un tamaño de cero en esta función UICollectionViewDelegate.
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section
{
if (section == 0) {
return CGSizeZero;
}else {
return CGSizeMake(self.collectionView.bounds.size.width, desiredHeight);
}
}
Intenta devolver una vista vacía. Probablemente sea una mejor manera pero esto podría funcionar ....
Noté que la respuesta aceptada se rompió cuando usaste AutoLayout en el XIB para el encabezado reutilizable.
Se rompió especialmente si separó el contenido de los bordes o si dio a los elementos dentro de la vista del encabezado un tamaño estático e inmutable. Al establecer el tamaño del encabezado en CGSizeZero, mi consola de depurador estaba llena de decenas de advertencias de Interface Builder que decían que romperían todas las restricciones para cumplir con el requisito establecido en el método de delegado.
Si bien eso en sí mismo no es técnicamente un desastre, todavía está sucio. Y en la era de Swift y AutoLayout tiene que haber una solución más limpia. Además, nunca desea enviar ese tipo de cosas a un cliente cuando está en el trabajo.
Para solucionar esto, en lugar de invocar a referenceSizeForHeaderInSection:
y al devolver CGSizeZero
, creé otra subclase de UICollectionReusableView
con XIB y establecí el alto de la vista en 0
.
Luego, más tarde, coloco esa variante fuera de la instrucción de switch
contenida en el método viewForSupplementaryElementOfKind
. ¡Esto satisface los requisitos de Interface Builder y visuales! 🎉
Los golpes tienen cientos de advertencias de restricciones insatisfactorias impresas en la Consola mientras estás depurando, de todos modos.
Tuve un caso con un UICollectionViewController
controla dos UICollectionView
s (referenciado más adelante como vista de colección 1 y 2) y quería encabezados a la primera y no encabezados (o pies de página) a la segunda.
Lo que falta en la respuesta de @mwright es que cuando devuelve CGSizeZero
para la vista de colección 2 de la siguiente manera:
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
if collectionView == self.collectionView2 {
return CGSizeZero
}
return < something else >
}
... significa que el collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView
no recibe ninguna llamada para la vista de colección 2 .
Lo que significa que no tiene que preocuparse por devolver un encabezado "incorrecto" para la segunda vista de colección en vano.