web-dev-qa-db-fra.com

Comment ajouter par en-tête par programme sur UICollectionView avec UICollectionViewLayout

J'ai un UICollectionView dans l'un de mes viewcontroller. Ma vue de collection utilise une sous-classe de UICollectionViewLayout (custom) pour mettre en forme les cellules. Tout d’abord, dès que je sélectionne Layout as Custom dans la liste déroulante de Storyboard, l’option permettant de sélectionner des vues supplémentaires disparaît. 

J'ai essayé de le faire par programme comme indiqué ci-dessous, mais aucune des méthodes de délégation n'est appelée.

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

        UICollectionReusableView *reusableview = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"HeaderView" forIndexPath:indexPath];

        if (reusableview==nil) {
            reusableview=[[UICollectionReusableView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
          }

        UILabel *label=[[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
        label.text=[NSString stringWithFormat:@"Recipe Group #%li", indexPath.section + 1];
        [reusableview addSubview:label];
        return reusableview;
      }
    return nil;
  }

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section {
    CGSize headerSize = CGSizeMake(320, 44);
    return headerSize;
  }

Dans ma méthode viewDidLoad, j'ai

[self.collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"HeaderView"];

Quelqu'un peut-il m'indiquer où je me trompe?

23
Manish Ahuja

Trouvé le problème, je ne renvoyais pas les attributs de mon en-tête dans cette méthode UICollectionLayoutView:

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect; // return an array layout attributes instances for all the views in the given rect
9
Manish Ahuja

Vous passez dans le genre de vue incorrecte.

Votre ligne d'inscription à la classe:

[self.collectionView registerClass:[UICollectionReusableView class]
  forSupplementaryViewOfKind:UICollectionElementKindSectionFooter
  withReuseIdentifier:@"HeaderView"];

Devrait être: 

[self.collectionView registerClass:[UICollectionReusableView class]
  forSupplementaryViewOfKind: UICollectionElementKindSectionHeader
  withReuseIdentifier:@"HeaderView"];

Edit : On dirait que votre code utilise entièrement sectionFooter. Essayez-vous d'ajouter par programme un en-tête ou un pied de page?

18
dannyzlo

Vérifiez que vous avez indiqué la taille de référence pour l'en-tête dans UICollectionViewFlowLayout

[flowLayout setHeaderReferenceSize:CGSizeMake(320, 50)];

et pour le pied de page 

[flowLayout setFooterReferenceSize:CGSizeMake(320, 50)];
8
Sukeshj

Votre méthode de délégué pour la taille de référence de l'en-tête est incorrecte, vous appelez la méthode du pied de page, referenceSizeForFooterInSection , comme suit:

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section {
  CGSize headerSize = CGSizeMake(320, 44);
  return headerSize;
}

Définir individuellement HeaderReferenceSize résoudra le problème de l'en-tête. Mais l'application va planter, vous allez conserver la méthode ci-dessus et renvoyer nil dans viewForSupplementaryElementOfKind for Footer.

1
Aaaaaron

votre chèque:

if (kind == UICollectionElementKindSectionFooter)

Vous devriez vérifier: UICollectionElementKindSectionHeader

pareil pour:

dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter

0
james075

Je pense que vous devriez appeler cela dans votre méthode viewdidload:

[collectionViewFlowLayout setHeaderReferenceSize:CGSizeMake(self.collectionView.frame.size.width, 50)];
0
Attia Mo