Eliminar el espacio vacío, si el encabezado de la sección está oculto en el UICollectionView


Tengo dos secciones en UICollectionView. Quiero mostrar un encabezado de sección en UICollectionView para solo la 1a sección. No en la sección 0.

Así que intenté devolver nil en viewForSupplementaryElementOfKind: método para section == 0 y devuelve la vista para section == 1.

Se bloquea y muestra el siguiente error:

Assertion failure in -[UICollectionView _createPreparedSupplementaryViewForElementOfKind:atIndexPath:withLayoutAttributes:applyAttributes]:

Aquí está mi código para la vista suplementaria.

- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
    UICollectionReusableView *sectionHeader = nil;
    if (kind == UICollectionElementKindSectionHeader && indexPath.section == 1) {
        sectionHeader = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"EventSectionHeader" forIndexPath:indexPath];
        sectionHeader.layer.borderWidth = .5f;
        sectionHeader.layer.borderColor = [UIColor colorWithRed:221.0 / 255.0 green:223.0 / 255.0 blue:220.0 / 255.0 alpha:1.0].CGColor;
    }

    return sectionHeader;
}

He encontrado que devolver nil en el método viewForSupplementaryElementOfKind: también se bloquea para otros. Otras respuestas que sugieren eliminar ese método.

Pero Yo desea mostrar el encabezado de la sección solo para secciones específicas. ¿Cómo lograr esa vista de retorno para una sola sección? Gracias. Cualquier ayuda sería apreciada.

EDITAR:

Como dijo @san, he actualizado el código para ocultar el encabezado de la sección. Funciona. Oculta el encabezado. Pero todavía estoy viendo el espacio vacío en el lugar del encabezado de la sección. Los resultados esperados es que no debe haber espacio para el encabezado de la sección, si está oculto.

Actualizado código:

- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{

    UICollectionReusableView *sectionHeader = nil;
    if (kind == UICollectionElementKindSectionHeader) {
        sectionHeader = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"EventSectionHeader" forIndexPath:indexPath];
        sectionHeader.layer.borderWidth = .5f;
        sectionHeader.layer.borderColor = [UIColor colorWithRed:221.0 / 255.0 green:223.0 / 255.0 blue:220.0 / 255.0 alpha:1.0].CGColor;
        if (indexPath.section == 0) {
            sectionHeader.hidden = YES;

        }else {
            sectionHeader.hidden = NO;
        }
    }

    return sectionHeader;
}

Incluso intenté establecer el marco para sectionHeader como dijo @san. Pero no hubo suerte. el mismo resultado.

Author: Dinesh Raja, 2013-11-18

4 answers

Por fin, encontré una respuesta a mi pregunta. Me he perdido algo. De todos modos lo siento por otros usuarios compañeros.

Establecí la altura y el ancho del encabezado dentro del método a continuación hasta ahora como dijo @san.

- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath

Pero no es el método correcto para establecer el tamaño del marco de las vistas suplementarias. Más tarde encontré otro método dentro del FlowLayout, que me ayuda a establecer los tamaños de encabezado y pie de página.

Esto realmente funciona bien para mí:

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section
{
    if (section == 0) {
        return CGSizeZero;
    }else {
        return CGSizeMake(CGRectGetWidth(collectionView.bounds), 135);
    }
}

ACTUALIZACIÓN: Desde que alguien preguntado sobre mi habilidad en comentarios, adjuntando Apple Documentation link para devolver CGSizeZero en el método anterior.

 78
Author: Dinesh Raja,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-29 04:43:59

La documentación para collectionView:viewForSupplementaryElementOfKind:atIndexPath: establece:

Este método siempre debe devolver un objeto view válido. Si no desea una vista suplementaria en un caso particular, su objeto de presentación no debe crear los atributos para esa vista. Alternativamente, puede ocultar vistas estableciendo la propiedad oculta de los atributos correspondientes en SÍ o estableciendo la propiedad alfa de los atributos en 0. Para ocultar las vistas de encabezado y pie de página en un diseño de flujo, también puede establecer el ancho y la altura de esas vistas a 0.

Teniendo en cuenta que ya ha intentado establecer la altura a cero y configurar la vista para que se oculte, debe subclase UICollectionViewFlowLayout e implementar layoutAttributesForSupplementaryViewOfKind:atIndexPath:

Compruebe el indexPath (como ya lo hace) y devuelva nil si no desea ningún atributo de diseño para esa vista suplementaria específica.

- (UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
    if([indexPath section] == 0)
    {
         return nil;
    }

    return [super layoutAttributesForSupplementaryViewOfKind:kind atIndexPath:indexPath];
}
 23
Author: CaptainRedmuff,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-20 11:54:01

La documentación dice claramente -

Valor devuelto

Un objeto de vista suplementario configurado. No debe devolver nil de este método.

Así que necesitas seguir -

Este método siempre debe devolver un objeto view válido. Si no desea una vista suplementaria en un caso particular, su objeto de presentación no debe crear los atributos para esa vista. Alternativamente, puede ocultar vistas configurando la propiedad oculta de la atributos correspondientes a SÍ o establecer la propiedad alfa de los atributos a 0. Para ocultar las vistas de encabezado y pie de página en un diseño de flujo, también puede establecer el ancho y el alto de esas vistas en 0.

Llegando a su código, el siguiente fragmento debería funcionar para usted:

- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
    UICollectionReusableView *sectionHeader = nil;
    if (kind == UICollectionElementKindSectionHeader) {
        sectionHeader = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"EventSectionHeader" forIndexPath:indexPath];

        if(indexPath.section == 1)
          {
             sectionHeader.layer.borderWidth = .5f;
             sectionHeader.layer.borderColor = [UIColor colorWithRed:221.0 / 255.0 green:223.0 / 255.0 blue:220.0 / 255.0 alpha:1.0].CGColor;
          }
        else
        {
          sectionHeader.frame = CGRectZero;
          sectionHeader.hidden = YES;
        }
    }

    return sectionHeader;
}
 10
Author: San,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-18 10:24:13

Puede ocultar / mostrar su sección de encabezado reutilizable agregando UICollectionViewDelegateFlowLayout delegado y utilizando el código siguiente

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section{
if (self.isForSearch) { //---> for hiding
    return CGSizeMake(0,0);
}
else{//---> for showing
    return ((UICollectionViewFlowLayout*)self.collectionChoosePlanView.collectionViewLayout).headerReferenceSize;
}
}

Para que puedas ocultarlo/mostrarlo

 -1
Author: Kaan Esin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-06 07:05:38