web-dev-qa-db-fra.com

La méthode UICollectionReusableView n'est pas appelée

Je veux que mes sections dans la UICollectionView aient un en-tête avec une image.

J'ai suivi ces étapes:

  • au storyboard, assigné un en-tête en tant qu'accessoire pour ma UICollectionView
  • lui a donné un identifiant
  • créé une sous-classe de UICollectionReusableView pour elle
  • assigné la classe personnalisée à la classe sur le storyboard.
  • mettre une ImageView à l'accessoire d'en-tête
  • créé un point de vente pour ImageView à la classe personnalisée dans le fichier .h
  • Implémentation de ce qui suit à viewDidLoad:

[self.collectionView registerClass:[ScheduleHeaderView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:headerIdentifier];

-(UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
    UICollectionReusableView *reusableview = nil;

    if (kind == UICollectionElementKindSectionHeader)
    {
        ScheduleHeaderView *headerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:headerIdentifier forIndexPath:indexPath];

        headerView.headerImageView.image = [UIImage imageNamed:@"blah.png"];

        reusableview = headerView;
    }

    return reusableview;
}

Je sais que les méthodes de source de données et de délégation fonctionnent, car je peux voir toutes les cellules et ses sections. Cependant, je n'ai pas mes en-têtes. J'ai mis un point d'arrêt à la méthode ci-dessus et il n'est jamais appelé.

Qu'est-ce que je fais mal?

53
Eden V.

Il semble que vous deviez donner à votre en-tête une taille différente de zéro ou que collectionView:viewForSupplementaryElementOfKind:atIndexPath ne soit pas appelé. Donc, définissez la propriété headerReferenceSize de la présentation du flux comme suit:

flowLayout.headerReferenceSize = CGSizeMake(self.collectionView.frame.size.width, 100.f);

ou, implémentez collectionView:layout:referenceSizeForHeaderInSection si vous souhaitez modifier la taille par section.

162
rdelmar

Vous avez répondu à la question, mais je comprends mieux les mots:

Pour que la méthode soit appelée, ajoutez ces méthodes:

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section {
    return CGSizeMake(60.0f, 30.0f);
}

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section {
    return CGSizeMake(60.0f, 30.0f);
}

... et à partir de là.

28
Pear Johan

Swift 4 Xcode 9.1 Beta 2

Ajouter @objc

@objc func collectionView(_ collectionView: UICollectionView, layout  collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize{
    let size = CGSize(width: 400, height: 50)
    return size
}

Crédits: https://medium.com/@zonble/your-delegation-methods-might-not-be-called-in-Swift-3-c6065ed7b4cd

14
cwilliamsz

Swift 3.0 (xcode 8.2.1)

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
        return CGSize(width:collectionView.frame.size.width, height:30.0)
    }
7
Xeieshan

Il y a la version Swift:

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
    let size = CGSize(width: 400, height: 50)
    return size
}

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize {
    let size = CGSize(width: 400, height: 50)
    return size
}

XCode (version 7.3.1) ne propose pas ces méthodes en autocomplétion!

Si vous voulez juste un en-tête, conservez la méthode d'en-tête.

5
Kevin ABRIOUX

Mon problème était que dans Swift 3, le nom de la fonction viewForSupplementaryElementOfKind a légèrement changé par rapport aux publications qui étaient sur le débordement de pile. Par conséquent, il n'a jamais été appelé. Si vous êtes dans Swift 3, assurez-vous que les fonctions de délégué correspondent:

func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {}
2
Daniel Jones

Pour moi, dans Swift 4.2, func collectionView (collectionView: kind: indexPath :) -> UICollectionReusableView n'a jamais été appelé. C'était pour une vue de collection dans un UIViewController. J'ai remarqué que les fonctions de vue de collection existantes étaient qualifiées avec @objc et qu'UICollectionView n'avait pas adopté les protocoles UICollectionViewDataSource et UICollectionViewDelegate. Dès que j'ai adopté les protocoles, j'ai eu des erreurs indiquant que les fonctions de la vue de collection ne correspondaient pas au protocole. J'ai corrigé la syntaxe de la fonction, supprimé les qualificatifs et les en-têtes de section ont commencé à fonctionner.

0
trishcode

J'ai le même problème. J'ai ajoutéreferenceSizeForFooterInSectionmais aussiviewForSupplementaryElementOfKindje ne me suis pas fait appeler . J'ai ajouté ce code dans viewDidLoad() et cela a fonctionné pour moi:

 if let flowLayout = self.collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
        flowLayout.sectionFootersPinToVisibleBounds = true

    }
0
Twinkle