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é?
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.
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
CellForItemAtIndexPath ne sera pas appelé si vous ne fournissez pas les informations de taille du contenu à la vue de collection.
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.
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.
Pour une hiérarchie de vue plus compliquée, veuillez vérifier ceci blog . Cela m'a sauvé la vie!
self.automaticallyAdjustsScrollViewInsets = NO;
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)
J'utilisais autolayout, et dans mon cas contrainte de hauteur manquante
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.
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é.
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:
Maintenant ça a marché :)
Dans mon cas, changer le translucide de UINavigationBar en NO a résolu le problème.
Cela se produisait pour moi lorsque la hauteur de l'élément == 0 en fixant la méthode cellForItem était appelée.
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.
Assurez-vous que numberOfSectionsInCollectionView
renvoie également un entier positif.
Il doit y avoir au moins une section dans la collection.
J'ai oublié de définir le masque autoresizing sur false dans la vue de collection:
collectionView.translatesAutoresizingMaskIntoConstraints = false
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.
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é.
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.
Dans la propriété UICollectionView de storyboard/xib, cellSize NE DOIT PAS être {0, 0}
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.
Dans mon cas, définissez collectionView.prefetchingEnabled = NO;
résolu mon problème. Ne fonctionne que sur iOS 10.
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).
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 {}
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];
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];
}