En essayant de décharger un lot d'images de la vue de collection et de les remplacer par un autre lot, je rencontre une erreur dans laquelle, selon que le groupe d'images d'origine ou ultérieur était supérieur ou inférieur au remplacement souhaité, une Une erreur d'assertion se produit qui dit:
*** Assertion failure in -[UICollectionViewData validateLayoutInRect:],
/SourceCache/UIKit_Sim/UIKit-2891.1/UICollectionViewData.m:341
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException',
reason: 'UICollectionView recieved layout attributes for a cell with an
index path that does not exist: <NSIndexPath: 0xb141c60> {length = 2, path = 0 - 2}
Dans ce cas, la liste existante du nombre d'images était 5 et la nouvelle liste d'images était donc 2. Ainsi, lorsqu'elle est arrivée à la troisième image - une exception s'est produite - indiquant que l'interface utilisateur CollectionViewDataDelegate n'était pas au courant du changement apporté au flux de données. .
Des suggestions sur la manière de vous assurer que les nouvelles images seront référencées par UICollectionView? Bien sûr, j'ai appelé 'reloadData'…
Je vous remercie
Je cours dans le même problème. Le code fonctionne sous 6.1 et se bloque sous 7.0 J'ai résolu le problème de la manière suivante:
Dans la fonction
-(NSInteger) numberOfSectionsInCollectionView:(UICollectionView *)collectionView
J'appelle
[myCollectionView.collectionViewLayout invalidateLayout];
C'est tout.
Avec iOS 10 et 11, cela aide:
collectionView.reloadData()
collectionView.collectionViewLayout.invalidateLayout()
La disposition invalide doit être APRÈS le rechargement des données.
Dominic Sander et user1544494 ont raison et leurs solutions sont bonnes.
Malheureusement, j'ai remarqué que si vous définissez minimumLineSpacingForSectionAtIndex
ou minimumInteritemSpacingForSectionAtIndex
, l'apparence de votre collectionView va se rompre (tôt ou tard).
Mettre invalidateLayout
dans viewWillLayoutSubviews
répond à cette question et aide à préserver l'aspect de viewCollection.
- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
[viewCollection.collectionViewLayout invalidateLayout];
}
C'est simple ... juste comme la phrase ci-dessous.
'UICollectionView recieved layout attributes for a cell with an
index path that does not exist: <NSIndexPath: 0xb141c60> {length = 2, path = 0 - 2}
Cela signifie qu'il n'y a pas indexPath (0,2) sur dataSouce . Mais votre UICollectionViewLayout renvoie un UICollectionViewLayoutAttributes pour indexPath (0,2).
Vous devez renvoyer UICollectionViewLayoutAttributes uniquement existant sur dataSouce.
Je pense que cela a changé de iOS7.
Mon problème était que j'avais deux UICollectionViews
dans une UIViewController
. Et j’avais les deux UICollectionViews
connectés à la même sous-classe UICollectionViewLayout
. J'ai résolu ce problème en modifiant chaque UICollectionView
pour avoir sa propre sous-classe UICollectionViewLayout
.
Source: Cette question
J'ai résolu ce problème en mettant à jour la source de données de ma vue de collection:
- (NSInteger)collectionView:(UICollectionView *)collectionView
numberOfItemsInSection:(NSInteger)section
{
[collectionView.collectionViewLayout invalidateLayout];
return collectionArray.count;
}
J'ai rencontré ce problème après avoir modifié le contenu de la vue Collection. La solution qui a fonctionné dans mon cas était d'invalider la mise en page après le rechargement. Le faire avant le rechargement ne fonctionnera pas.
[collectionView reloadData];
//forces the layout attributes to be recalculated for new data
[collectionView.collectionViewLayout invalidateLayout];
La solution que j'ai trouvée consistait à vérifier que la variable indexPath
que je créais dans la méthode layoutAttributesForElementsInRect(rect: CGRect) -> [AnyObject]?
était valide pour la ligne. Auparavant, j'utilisais (où i
est mon compteur de boucles):
var indexPath = NSIndexPath(index: i)
var attributes = UICollectionViewLayoutAttributes(forCellWithIndexPath: indexPath)
Mais le mettre à jour pour utiliser ce qui suit l'a résolu:
var indexPath = NSIndexPath(forRow: i, inSection: 0)!
var attributes = UICollectionViewLayoutAttributes(forCellWithIndexPath: indexPath)
J'ai pu résoudre ce problème en créant une sous-classe de UICollectionViewFlowLayout
et en surchargeant cette méthode pour renvoyer YES
:
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
return YES;
}
J'ai rencontré quelque chose de similaire lorsque j'essayais de dupliquer une vue de collection dans un autre storyboard.
'UICollectionView a reçu des attributs de mise en page pour une cellule avec un index chemin qui n'existe pas: {longueur = 2, chemin = 1 - 0} '
Au début, je cherche une solution rapide. Essayé copier coller différentes réponses StackOverflow.
Mais j'ai écrit mon propre cours de mise en page. J'essaie donc de déboguer discrètement, cela pourrait être ma mise en cause, non? Constaté que la méthode numberOfSections
n'a jamais été appelée. La vue de collection supposait qu’elle n’avait qu’une section.
Ensuite, j'ai trouvé que la classe du contrôleur de vue avait oublié de se conformer à UICollectionViewDataSource
. Bien que la source de données soit connectée au storyboard, la classe du contrôleur de vue sera probablement downcast, comme if let ds = dataSource as? UICollectionViewDataSource {ds.numberOfSections...}
, qui échouerait en mode silencieux.
J'ai donc ajouté la conformité à UICollectionViewDataSource
et tout fonctionne bien. Mon hypothèse pourrait être inexacte. Mais la leçon à tirer est qu’à chaque fois qu’un bogue dont vous n’êtes pas familier se lève, installez-vous et comprenez-le.UICollectionView a reçu les attributs de mise en forme pour une cellule dont le chemin d'index n'existe pas, cela signifie exactement ce qu'il dit. Pas si dur que ça? N'essayez pas de trouver une solution miracle, comme beaucoup de réponses ici. Ils sont tous excellents mais votre code est le véritable lieu de bataille.
Dans mon cas, j'avais une coutume UICollectionViewFlowLayout
. Après avoir supprimé les cellules de la collection, l'application s'est écrasée. Le correctif était de removeAll()
attributs précédemment calculés. Ainsi, la première ligne après override func prepare()
est arrayHoldingYourAttributes.removeAll()
.
J'ai rencontré ce problème et c'était assez énervant. Ma solution est d'oublier UICollectionViewController
et d'utiliser à la place des UIViewController
ordinaires avec des UICollectionView
à l'intérieur.
Cela signifie qu'il n'y a pas indexPath (0,2) sur dataSouce. Cependant, votre UICollectionViewLayout renvoie un UICollectionViewLayoutAttributes pour indexPath (0,2). Par TopChul
C'est vrai! Pour moi, le problème est dû au fait que j'utilise la même disposition de collection (instance) pour deux collectionView! Donc, cette mise en page confondue entre deux vues de collection.
Cela fonctionne bien après que j'utilise une disposition différente entre différentes vues de collection.
J'ai aussi eu ce bogue et j'ai trouvé une solution de contournement. Pour moi, UICollectionView le lançait sous iOS 7, fonctionnant parfaitement sous iOS 8.
Consultez cet article: Qu'est-ce qui cause ce crash iOS? UICollectionView a reçu des attributs de mise en page pour une cellule avec un chemin d'index inexistant
En 2 mots: Mise en page automatique. Désactivez-le sur la vue contenant UICollectionView et pour moi, cela a fonctionné.
Assurez-vous de mettre à jour la contentSize
de votre collectionViewLayout
. Ainsi, après avoir obtenu de nouvelles images (2 au lieu de 5), recalculez la variable contentSize
et définissez-la.
J'ai eu un problème similaire (en utilisant Swift2.0, XCode 7).
L'application s'est écrasée avec UICollectionView received layout attributes for a cell with an index path that does not exist
...
Dans mon cas, depuis que j'ai utilisé le storyboard, il s'est avéré que j'avais oublié de connecter l'IBOutlet défini dans mon viewController avec la collection collectionView définie dans le storyboard. Connecter les deux a résolu le problème.
Je rencontre le même problème lorsque j'utilise UICollectionViewFlowLayout
en tant que CollectionView's collectionViewLayout
.
Déclarer le parent viewController
implémenté UICollectionViewDelegateFlowLayout
et l'affecter comme délégué collectionView
peut résoudre ce problème.
Je l'ai compris . Si vous utilisez nib/xib pour organiser vos UITableViewCell
et niché UICollectionView
, vous pouvez éviter cette erreur en surchargeant cette méthode.
- (void)prepareForReuse {
[super prepareForReuse];
[self.collectionView.collectionViewLayout invalidateLayout];
}
J'espère que ça aide.
CollectionViewLayout met en cache les attributs de présentation . Créez une nouvelle instance de collectionViewLayout et affectez-la à collectionview.collectionViewLayout. Cela a fonctionné pour moi, en particulier lorsque vous utilisez d'autres bibliothèques collectionViewLayout.