web-dev-qa-db-fra.com

UICollectionView cellForItemAtIndexPath n'est pas appelé.

Ce n’est que la deuxième fois que j’utilise UICollectionView et j’en ai peut-être mordu plus que je ne peux en mâcher, mais néanmoins:

J'implémente UICollectionView (myCollectionView) qui utilise des UICollectionViewCell personnalisés que j'ai sous-classés. Les cellules sous-classées (FullReceiptCell) contiennent UITableView et ont la taille du contrôleur de vue. J'essaie de permettre le défilement horizontal entre les FullReceiptCells.

Le sous-groupe UICollectionViewController contenant myCollectionView est en cours d'installation sur une pile de contrôleurs de navigation. Actuellement, myCollectionView loas et le défilement horizontal sont activés. Cependant, aucune cellule n'est visible. J'ai confirmé que

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section

a été exécuté et renvoie un entier supérieur à 0. J'ai également confirmé que le délégué et la source de données de myCollectionView sont correctement définis dans IB pour le sous-groupe UICollectionViewController.

La méthode où les cellules doivent être chargées:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath

n'est pas appelé.

Voici où j'appuie UICollectionViewController et ma méthode viewDidLoad au sein de ce contrôleur (REMARQUE: initWithBill est un remplacement de l'initialiseur normal):

Dans l'ancien fichier ViewControllers .m:

FullReceiptViewController *test = [[FullReceiptViewController alloc] initWithBill:currentBill];
test.title = @"Review";
[self.navigationController pushViewController:test animated:YES];

Dans FullReceiptViewController.m:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    [self.myCollectionView registerClass:[FullReceiptCell class] forCellWithReuseIdentifier:@"FullReceiptCellIdentifier"];
    self.myCollectionView.pagingEnabled = YES;
    // Setup flowlayout

    self.myCollectionViewFlowLayout = [[UICollectionViewFlowLayout alloc] init];
    [self.myCollectionViewFlowLayout setItemSize:CGSizeMake(320, 548)];
    [self.myCollectionViewFlowLayout setSectionInset:UIEdgeInsetsMake(0, 0, 0, 0)];
    [self.myCollectionViewFlowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
    self.myCollectionViewFlowLayout.minimumLineSpacing = 0;
    self.myCollectionViewFlowLayout.minimumInteritemSpacing = 0;
    [self.myCollectionView setCollectionViewLayout:myCollectionViewFlowLayout];
    //testing to see if the collection view is loading
    self.myCollectionView.backgroundColor = [UIColor colorWithWhite:0.25f alpha:1.0f];

Aucune idée quant à pourquoi il n'est pas appelé?

91
IkegawaTaro

Pour ceux qui trébuchent ici plus tard ... la raison:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath

n'a pas été appelé en raison de la taille de l'élément pour la collectionViewFlowLayout était trop grande.

[self.myCollectionViewFlowLayout setItemSize:CGSizeMake(320, 548)];

Si je modifie la hauteur à 410, il exécutera cellForItemAtIndexPath.

122
IkegawaTaro

Dans mon cas, c’est parce que ma classe de mise en page s’est mal subdivisée à partir de UICollectionViewLayout au lieu de UICollectionViewFlowLayout

81
esilver

CellForItemAtIndexPath ne sera pas appelé si vous ne fournissez pas les informations de taille du contenu à la vue de collection.

  1. Si vous utilisez une disposition de flux: Vous devez définir les tailles des éléments correctement.
  2. Si vous avez une mise en page personnalisée sous-classée à partir de UICollectionViewLayout: assurez-vous de retourner une taille appropriée à partir de la méthode collectionViewContentSize.

Dans ce dernier cas, vous remarquerez également que votre ( layoutAttributesForElementsRect n'est pas non plus appelé. La raison en est que vous n'avez pas spécifié quelle est la taille de votre contenu et que par défaut, la taille sera CGSizeZero. En gros, cela indique à la vue de collection que vous n'avez aucun contenu à Paint, donc cela ne vous dérange pas de vous demander des attributs ou des cellules.

Donc, remplacez simplement collectionViewContentSize et fournissez une taille appropriée, cela devrait résoudre votre problème.

24
Deepak G M

Peut-être suis-je en train de l'ignorer, mais il semble que votre délégué et votre source de données soient manquants. Dans votre fichier d’en-tête, assurez-vous d’avoir ajouté les éléments suivants:

<UICollectionViewDelegate, UICollectionViewDataSource>

et dans votre méthode viewDidLoad, ajoutez ceci:

self.myCollectionView.delegate = self;
self.myCollectionView.dataSource = self;

De plus, si vous le chargez via un fichier .xib, assurez-vous que vous avez connecté l'IBOutlet à UICollectionView.

15
Anthony Castelli

Pour une hiérarchie de vue plus compliquée, veuillez vérifier ceci blog . Cela m'a sauvé la vie!

self.automaticallyAdjustsScrollViewInsets = NO;
14
Jaybo

Si votre classe est une sous-classe de UICollectionviewController et que vous créez collectionView par programme, utilisez

let layout = UICollectionViewFlowLayout()
    layout.scrollDirection = .Vertical
    layout.itemSize = CGSizeMake(50, 50)

    collectionView?.setCollectionViewLayout(layout, animated: false)
12
GSK

J'utilisais autolayout, et dans mon cas contrainte de hauteur manquante

7
AamirR

Dans mon cas, ce que j'avais très bêtement oublié de faire, c’était d’appliquer la méthode de protocole UICollectionViewDataSource, numberOfItemsInSection, c’est donc une autre chose à vérifier.

4
Dean

Mon problème était que j'avais 2 vues de collection dans la même vue et que les deux partageaient une instance calculée UICollectionViewFlowLayout. Une fois que j'ai créé des instances distinctes du même agencement de flux, cela a bien fonctionné.

4
nebyark

Dans Xcode 7.0.1, nous avons eu ce problème lorsque nous avons copié un storyboard et le code d’accompagnement d’un autre projet. La vue de collection avait une disposition de flux personnalisée définie dans le storyboard. La solution était de:

  • Supprimer la structure de flux dans IB
  • Compiler/exécuter l'application
  • Régler la disposition du flux

Maintenant ça a marché :)

3
Bart van Kuik

Dans mon cas, changer le translucide de UINavigationBar en NO a résolu le problème.

3
chanil

Cela se produisait pour moi lorsque la hauteur de l'élément == 0 en fixant la méthode cellForItem était appelée.

3
Jirune

Il y a dix minutes, j'ai également rencontré ce problème, j'ai commis une erreur stupide.

Mon intention est d’utiliser UICollectionViewFlowLayout,

Mais à cause d’erreurs, j’ai utilisé UICollectionViewLayout.

3
Vincent

Assurez-vous que numberOfSectionsInCollectionView renvoie également un entier positif.

Il doit y avoir au moins une section dans la collection.

2
Eran Goldin

J'ai oublié de définir le masque autoresizing sur false dans la vue de collection:

collectionView.translatesAutoresizingMaskIntoConstraints = false
2
Stritt

Il peut être réalisé des problèmes de mise en page. Vérifiez les avertissements de mise en page à partir de la console, le cas échéant.

2
erdikanik

Dans mon cas, la vue Collection n'était pas entièrement visible dans la vue parent en raison de contraintes de mise en page automatique incorrectes. Donc, en corrigeant les contraintes, la vue de la collection était entièrement visible et cellForItemAtIndexPath était appelé.

2
Khaled Annajar

Assurez-vous que - (NSInteger) collectionView: numberOfItemsInSection: renvoie une valeur positive (lecture, supérieure à zéro). Il peut s'agir de placer [self.collectionView reloadData]; dans le gestionnaire d'achèvement.

2
RT Denver

Si vous utilisez des protocoles de vue de collection, vous devez connecter les protocoles CollectionViewDataSource et CollectionViewDataSource à votre ViewController. Interface builder outlets

2
Declan McKenna

Dans la propriété UICollectionView de storyboard/xib, cellSize NE DOIT PAS être {0, 0}

2
poGUIst

La même chose m'est arrivé. J'ai eu 2 UICollectionViews et j'ai enlevé une fois car je n'avais pas besoin de ça. Après cela, j'ai réalisé que CellForItemAtIndexPath n'était pas appelé, mais les autres méthodes requises. J'ai essayé tout ce qui précède, mais j'ai ensuite utilisé la magie standard. Suppression de la vue de collection du storyboard et ajout de nouveau. Ensuite, cela a commencé à fonctionner. Je ne sais pas pourquoi et je n'ai aucune explication, mais peut-être quelques problèmes de connexion.

1
Hafeez

Dans mon cas, définissez collectionView.prefetchingEnabled = NO; résolu mon problème. Ne fonctionne que sur iOS 10.

1
6david9

Assurez-vous également que reloadData n'est pas appelé lorsque la vue de collection se met à jour avec une animation (insérer, supprimer, mettre à jour ou effectuerBatchUpdates).

1
sasha_nec

Lorsque vous utilisez UICollectionViewDelegateFlowLayout, faites attention à ce que cette fonction retourne. width et height devraient tous deux être supérieurs à 0. J'ai utilisé window comme référence d'image, mais en raison de la complexité de la hiérarchie de vues, la fenêtre était nil à l'exécution. Si vous avez besoin d'ajuster la largeur de l'élément en fonction de la largeur de l'écran, utilisez UIScreen.main.bounds.

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: 
           UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {}
1
inokey

Pour moi, je mets à jour la hauteur de self.view (le superview de la collectionView) via autolayout, et DOIT appeler layoutIfNeeded après cela.

[self.view mas_updateConstraints:^(MASConstraintMaker *make) {
    make.height.equalTo(@(height));
}];
[self.view layoutIfNeeded];
0
iwill

Juste résolu ce problème, pour une situation quelque peu spécifique.

Dans mon cas, j'initialisais manuellement UICollectionViewController dans un ViewController parent, puis j'ajoutais la vue de UICollectionViewController en tant que sous-vue.

J'ai résolu le problème en appelant 'setNeedsLayout' et/ou 'setNeedsDisplay' sur la collectionView dans le viewDidAppear du parent:

- (void)viewDidAppear:(BOOL)animated {
   [super viewDidAppear:animated];
   [_collection.view setNeedsLayout];
   [_collection.view setNeedsDisplay];
}
0
Tim