web-dev-qa-db-fra.com

UICollectionViewcell en train de disparaître

Que ce passe-t-il

Actuellement, j'ai une application qui utilise deux UICollectionViews dans une UITableView. De cette façon, je crée un Pulse News qui ressemble à une application. Mon problème avec cela est que parfois les 6ème et 11ème lignes disparaissent complètement, laissant un espace vide où il devrait être la cellule. Cela ne me dérangerait pas si toutes les cellules étaient comme ça (et de cette façon, je pourrais supposer que je ne faisais pas les choses correctement), mais le problème est que cela ne fait que se produire avec ces cellules spécifiques.

Ma théorie

Les 6ème et 11ème rangées sont celles qui apparaissent lorsque je commence à faire défiler. Ainsi, par défaut, je peux voir 5 cellules et lorsque je fais le premier défilement horizontal, la 6ème apparaît (espace vide parfois). 

Ce que j'ai

La seule chose que je fasse en ce moment est la suivante:

 [self.collectionView registerNib:[UINib nibWithNibName:CELL_NIB_NAME bundle:nil] forCellWithReuseIdentifier:CELL_IDENTIFIER];

Sur la viewDidLoad. Et sur la création de la cellule:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    MyCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CELL_IDENTIFIER forIndexPath:indexPath];

    NSMutableDictionary *dictionary = [self.DataSource objectAtIndex:[indexPath row]];

    [cell buildViewWithDictionary:dictionary withReferenceParent:self.referenceViewController];

    return cell;
}

Donc, si je comprends bien, rien d’extraordinaire ne se passe ici. Je pensais qu'il y avait quelque chose qui n'allait pas dans la source de données (un fichier JSON factice), mais parfois cela fonctionne bien et la cellule s'affiche, donc je suppose qu'à partir de cette partie, tout va bien. 

Donc ma "question": Est-ce que quelqu'un sait ce qui se passe? Je n'aime pas trop dire que c'est un bug d'iOS, mais je ne peux penser à rien d'autre.


Edit 1.0

La partie étonnante est que cette méthode

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

Va de indexPath [0,4] à [0,6] sans calculer le [0,5]. C'est la première fois que je vois cela se produire dans iOS.


Edit 2.0

J'ai changé la façon dont je crée les cellules et, au lieu de retirer de la file d'attente, j'utilise l'ancienne méthode:

NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CELL_NIB_NAME owner:self options:nil];
MyCell *cell = (MyCell *)[nib objectAtIndex:0];

Toujours le même résultat triste.

52
Rui Peres

Alors, qu'est-ce qui a fonctionné? 

1) Sous-classe UICollectionViewFlowLayout.

2) Définissez le flowLayout de ma UICollectionView sur ma nouvelle sous-classe.

3) Sur la méthode init de la sous-classe UICollectionViewFlowLayout, définissez l'orientation souhaitée:

self.scrollDirection = UICollectionViewScrollDirectionHorizontal;

Dans mon cas, c'est horizontal.

4) La partie importante :

-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
   return YES;
}

En ce moment, je devrais théoriser un peu, mais honnêtement, je n'en ai aucune idée. 

34
Rui Peres

Les réponses ci-dessus n'ont pas fonctionné pour moi, mais après avoir téléchargé les images, j'ai remplacé le code [self.myCollectionView reloadData] Par [self.myCollectionView reloadSections:[NSIndexSet indexSetWithIndex:0]];

12
Yao Li

Aucune des solutions proposées par quiconque ne m'a aidé dans ma mise en page personnalisée que nous devons avoir dans notre application . Au lieu de cela, je devais le faire: (Et oui, IT WORKS !!!)

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect{
    CGSize size = [self collectionViewContentSize];
    rect.size.height = size.height*2;
    NSArray *atrributes_Super = [super layoutAttributesForElementsInRect:rect];
    return atrributes_Super;
}

Après tout, UICollectionView ne fait que rechercher les attributs des éléments à afficher dans le rect de votre écran.

6
CoderSaru

Le conseil de Rob concernant le virus m'a aidé. Le bogue indique que si la largeur et l’espacement des incrustations de section et des cellules s’additionnent exactement à la largeur de l’écran, la première colonne disparaît parfois de manière aléatoire et réapparaît pour certaines cellules à certains endroits. Plutôt que de sous-classer ou de modifier la largeur des cellules, j'ai modifié de 6 à 4 les encarts de section pour les côtés gauche et droit de mon story-board et je n'ai plus revu le problème.

3
hoak

Alors que je me suis soudainement retrouvé confronté au même problème et que j'ai passé quelque temps à comprendre l'une des raisons possibles de la disparition d'une cellule pendant le défilement, je vais également ajouter ma réponse.

Prérequis du problème:

  1. Vous avez une instance UICollectionView
  2. Vous avez une UICollectionViewFlowLayoutSubclass

Le problème

Les cellules disparaissent de la vue Collection après le défilement jusqu'au moment voulu.

La source du problème réside dans la mauvaise sous-classification de UICollectionViewFlowLayout.

Comme il est dit explicitement dans documentation :

Chaque objet de présentation doit implémenter les méthodes suivantes:

- collectionViewContentSize
- layoutAttributesForElements(in:)
- layoutAttributesForItem(at:)
- layoutAttributesForSupplementaryView(ofKind:at:) // (if your layout supports -supplementary views)
-layoutAttributesForDecorationView(ofKind:at:) // (if your layout supports decoration views)
- shouldInvalidateLayout(forBoundsChange:)

En nous appuyant sur la méthode UICollectionViewFlowLayout des méthodes ci-dessus, nous oublions le fait que func layoutAttributesForElements(in rect: CGRect) et collectionViewContentSize génèreront une erreur contentSize (la taille qui serait correcte si toutes les cellules avaient la taille itemSize et la taille du contenu correspondait. A bientôt car scroll offsetY sera plus grand que contentSize height que la cellule disparaîtra. 

La solution

La solution est dans le sous-classement UICollectionViewFlowLayout approprié. Remplacez toutes les méthodes qui sont obligatoires et tout fonctionnera correctement.

2
fewlinesofcode

Dans mon cas (défilement vertical, les cellules disparaissant dans la première vue), les cellules disparaissaient en raison d'une taille estimée incorrecte. Il semble que UICollectionView utilise la taille estimée pour calculer les éléments à charger dans la première vue. J'avais réglé la taille estimée trop élevée, ce qui entraînait des calculs erronés pour le nombre d'éléments à charger dans le premier écran.

Dès que la hauteur estimée a été réduite, toutes les cellules sont apparues correctement. 

1
chandan thakur

Pour moi, ce problème semblait être lié à la façon dont je fais en sorte que ma collectionview s’adapte à un clavier ouvert pour éviter les chevauchements de contenu.

dans mon observateur pour répondre à KeyboardWillShow j'avais ceci:

var userInfo = obj.UserInfo[UIKeyboard.FrameEndUserInfoKey];
if (userInfo is NSValue value)
{
    var rect = value.CGRectValue;
    var windowOffset = this.Superview.ConvertPointToView(this.Frame.Location, UIApplication.SharedApplication.KeyWindow);
    var newHeight = rect.Y - windowOffset.Y;

    this._controller.CollectionView.Frame = new CGRect(0, 0, this._controller.CollectionView.Frame.Width, newHeight);
}

Après l'avoir changé en ceci:

var userInfo = obj.UserInfo[UIKeyboard.FrameBeginUserInfoKey];
if (userInfo is NSValue value)
{
    var rect = value.CGRectValue;
    UIEdgeInsets contentInsets = new UIEdgeInsets(0, 0, rect.Height, 0);
    this._controller.CollectionView.ContentInset = contentInsets;
    this._controller.CollectionView.ScrollIndicatorInsets = contentInsets;
}

La question de la disparition de la cellule a complètement disparu. C # est issu de ma collaboration avec xamarin, mais j’espère que cela aidera quelqu'un d’autre.

0
Dbl

Je pense que ce n’est pas un bogue de UICollectionView, il est possible que vous ne renvoyiez pas les bonnes données dans la méthode - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect.

Vous pouvez voir cette démonstration: https://github.com/lqcjdx/YLTagsChooser , toutes les cellules peuvent apparaître lors du défilement de UICollectionView.

0
lambert.lu

Nous avons rencontré récemment des cellules en train de disparaître et avons découvert que, plutôt que de sauter des cellules "cachées", nous avons accidentellement inséré des cellules de taille 0x0. Le comportement qui en a résulté était très déroutant et ne laissait pas penser que ces cellules invisibles étaient en cause. Nous verrions les cellules et la disposition correctement dimensionnées, mais quelques-unes des cellules valides disparaîtraient systématiquement après un défilement à l'écran. Je ne sais pas pourquoi le fait de mêler des cellules de taille 0 provoquerait ce problème, mais leur suppression a résolu le problème. Cela n’est peut-être pas la cause de votre problème, mais cela peut être utile aux développeurs à la recherche de symptômes similaires. 

0
tyler