web-dev-qa-db-fra.com

Supprimer un espace vide si l'en-tête de la section est masqué dans UICollectionView

J'ai deux sections dans UICollectionView. Je veux montrer un en-tête de section dans UICollectionView pour seulement la 1ère section. Pas dans la 0ème section.

J'ai donc essayé de renvoyer nil dans viewForSupplementaryElementOfKind: méthode pour section == 0 et renvoie la vue pour section == 1.

Il se bloque et affiche l'erreur ci-dessous:

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

Ici c'est mon code pour la vue supplémentaire.

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

J'ai trouvé que renvoyer nil dans la méthode viewForSupplementaryElementOfKind: plante pour les autres aussi. Autres réponses suggérant de supprimer cette méthode. 

Mais je veux montrer en-tête de section pour des sections spécifiques seulement. Comment obtenir cette vue de retour pour une seule section? Merci. Toute aide serait appréciée.

MODIFIER:

Comme @san l'a dit, j'ai mis à jour le code pour masquer l'en-tête de section. Ça marche. Il cache l'en-tête. Mais je vois toujours l'espace vide à la place de l'en-tête de section. Les résultats attendus sont qu'il ne devrait pas y avoir d'espace pour l'en-tête de section, s'il est masqué.

code mis à jour:

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

J'ai même essayé de définir le cadre pour sectionHeader comme @san a dit. Mais pas de chance. même résultat.

39
Dinesh Raja

Enfin, j'ai trouvé une réponse à ma question. J'ai raté quelque chose. Quoi qu'il en soit, désolé pour les autres utilisateurs.

J'ai défini la hauteur et la largeur de l'en-tête dans la méthode ci-dessous jusqu'à présent, comme @san l'a dit.

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

Mais ce n'est pas la bonne méthode pour définir la taille de trame des vues supplémentaires. Plus tard, j'ai trouvé une autre méthode dans flowLayout, qui m'aide à définir les tailles d'en-tête et de pied de page.

Cela fonctionne vraiment bien pour moi:

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

UPDATE: Depuis que quelqu'un m'interrogeait sur ses compétences en commentaires, ajoutait le lien Apple Documentation pour renvoyer CGSizeZero à la méthode ci-dessus. 

80
Dinesh Raja

La documentation de collectionView:viewForSupplementaryElementOfKind:atIndexPath: indique:

Cette méthode doit toujours renvoyer un objet de vue valide. Si vous ne souhaitez pas de vue supplémentaire dans un cas particulier, votre objet de modèle ne doit pas créer les attributs pour cette vue. Vous pouvez également masquer des vues en définissant la propriété masquée des attributs correspondants sur YES ou en définissant la propriété alpha des attributs sur 0. Pour masquer les vues d'en-tête et de pied de page dans une présentation de flux, vous pouvez également définir la largeur et la hauteur de ces vues. à 0.

Étant donné que vous avez déjà essayé de définir la hauteur à zéro et de masquer la vue, vous devez sous-classer UICollectionViewFlowLayout et implémenter layoutAttributesForSupplementaryViewOfKind:atIndexPath:.

Vérifiez le chemin indexPath (comme vous le faites déjà) et renvoyez nil si vous ne voulez pas d'attributs de présentation pour cette vue supplémentaire spécifique.

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

    return [super layoutAttributesForSupplementaryViewOfKind:kind atIndexPath:indexPath];
}
23
CaptainRedmuff

La documentation dit clairement - 

Valeur de retour

Un objet de vue supplémentaire configuré. Vous ne devez pas renvoyer nil de cette méthode.

Donc, vous devez suivre -

Cette méthode doit toujours renvoyer un objet de vue valide. Si vous ne souhaitez pas de vue supplémentaire dans un cas particulier, votre objet de modèle ne doit pas créer les attributs pour cette vue. Vous pouvez également masquer des vues en définissant la propriété masquée des attributs correspondants sur YES ou en définissant la propriété alpha des attributs sur 0. Pour masquer les vues d'en-tête et de pied de page dans une présentation de flux, vous pouvez également définir la largeur et la hauteur de ces vues. à 0.

Venant à votre code, le code ci-dessous devrait fonctionner pour vous:

- (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
San

Dans mon cas, j'ai inséré des sections dans les sections, de sorte qu'il me donnait un espace vide.

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        if <condition for which you want to hide section>{
            return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
        }else{
            return UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
        }
    }
0
Nikunj Acharya