web-dev-qa-db-fra.com

Redimensionner les cellules UICollectionView une fois leurs données définies

Mes cellules UICollectionView contiennent des étiquettes UIL avec du texte multiligne. Je ne connais pas la hauteur des cellules tant que le texte n'a pas été défini sur l'étiquette.

-(CGSize)collectionView:(UICollectionView *)collectionView
                 layout:(UICollectionViewLayout*)collectionViewLayout
 sizeForItemAtIndexPath:(NSIndexPath *)indexPath;

C'était la méthode initiale que j'ai étudiée pour dimensionner les cellules. Cependant, cela s'appelle AVANT que les cellules ne soient créées à partir du storyboard.

Existe-t-il un moyen de disposer la collection et de dimensionner les cellules APRÈS leur rendu, et je connais la taille réelle de la cellule?

48
Shocks

Je pense que vous recherchez la méthode invalidateLayout que vous pouvez appeler sur .collectionViewLayout propriété de votre UICollectionView. Cette méthode régénère votre mise en page, ce qui dans votre cas signifie également appeler -collectionView: layout: sizeForItemAtIndexPath:, qui est le bon endroit pour refléter la taille de votre article. Jirune indique la bonne direction pour les calculer.

Un exemple d'utilisation de invalidateLayout peut être trouvé ici . Consultez également la documentation UICollectionViewLayout sur cette méthode:

Invalide la disposition actuelle et déclenche une mise à jour de la disposition.

Discussion:

Vous pouvez appeler cette méthode à tout moment pour mettre à jour les informations de mise en page. Cette méthode invalide la disposition de la vue de la collection elle-même et revient immédiatement. Ainsi, vous pouvez appeler cette méthode plusieurs fois à partir du même bloc de code sans déclencher plusieurs mises à jour de mise en page. La mise à jour de la mise en page réelle se produit lors du prochain cycle de mise à jour de la mise en page de la vue.

Modifier:

Pour la vue de collection de storyboard qui contient des contraintes de disposition automatique, vous devez remplacer la méthode viewDidLayoutSubviews de UIViewController et appeler invalidateLayout la disposition de vue de collection dans cette méthode.

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    [yourCollectionView.collectionViewLayout invalidateLayout];
}
72
Ignatius Tremor

sous-classe UICollectionViewCell et remplacer layoutSubviews comme ceci

par la présente, vous ancrez le bord d'attaque et de fuite de la cellule à collectionView

override func layoutSubviews() {
        super.layoutSubviews()

        self.frame = CGRectMake(0, self.frame.Origin.y, self.superview!.frame.size.width, self.frame.size.height)
    }
5
János

Hé dans la méthode delegate ci-dessus elle-même, vous pouvez calculer la taille UILabel en utilisant la méthode délicate ci-dessous et renvoyer le UICollectionViewCellsize en fonction de ce calcul.

    // Calculate the expected size based on the font and 
    // linebreak mode of your label
    CGSize maximumLabelSize = CGSizeMake(9999,9999);

    CGSize expectedLabelSize = 
     [[self.dataSource objectAtIndex:indexPath.item] 
             sizeWithFont:[UIFont fontWithName:@"Arial" size:18.0f] 
        constrainedToSize:maximumLabelSize 
            lineBreakMode:NSLineBreakByWordWrapping];
4
Jirune
- (void)viewDidLoad {
    self.collectionView.prefetchingEnabled = NO;
}

Dans iOS 10, prefetchingEnabled est YES par défaut. Lorsque YES, la vue de collection demande des cellules avant de les afficher. Cela conduit à planter dans iOS 10

2
Sakshi Jain