web-dev-qa-db-fra.com

Comment ajuster la hauteur de UICollectionView afin qu'elle corresponde à la taille du contenu de UICollectionView?

J'aimerais que UICollectionView (le rouge) soit réduit à la hauteur de la taille du contenu, dans ce cas, UICollectionViewCells (les jaunes), car il y a beaucoup d'espace vide. Ce que j'ai essayé, c'est d'utiliser:

override func layoutSubviews() {
    super.layoutSubviews()
    if !__CGSizeEqualToSize(bounds.size, self.intrinsicContentSize) {
        self.invalidateIntrinsicContentSize()
    }
}

override var intrinsicContentSize: CGSize {
    return self.collection.contentSize
}

mais return self.collection.contentSize renvoie toujours (width, 0) Et pour cette raison, il se réduit trop à la valeur de height 30 (valeur que j'ai définie dans le fichier xib pour la hauteur, bien que constaint> = 30).

 enter image description here

35
charbinary

Je suggérerais ce qui suit:

  1. Ajoutez une contrainte de hauteur à votre vue de collection.
  2. Définissez sa priorité sur 999.
  3. Définissez sa constante sur toute valeur ne la rendant que raisonnablement visible sur le storyboard.
  4. Définissez la contrainte inférieure égale de la vue de collection sur supérieure ou égale.
  5. Connectez la contrainte de hauteur à une prise.
  6. Chaque fois que vous rechargez les données dans la vue Collection, procédez comme suit:

Exemple de code:

CGFloat height = myCollectionView.collectionViewLayout.collectionViewContentSize.height
heightConstraint.constant = height
self.view.setNeedsLayout() Or self.view.layoutIfNeeded()

Explication: Extra, vous n'êtes pas obligé de lire si vous le comprenez. évidemment!!

L'interface utilisateur essaiera de refléter toutes les contraintes, quelles que soient leurs priorités. Puisque la contrainte de hauteur a une priorité inférieure de (999), et une contrainte de bas de type supérieure ou égale. chaque fois que la constante de contrainte de hauteur est définie sur une valeur inférieure à la hauteur de la vue parente, la vue de collection sera égale à la hauteur donnée, ce qui permet d'atteindre les deux contraintes.

Toutefois, lorsque la constante de contrainte de hauteur définie est supérieure à la hauteur de la vue parent, les deux contraintes ne peuvent pas être atteintes. Par conséquent, seule la contrainte ayant la priorité la plus élevée sera atteinte, à savoir la contrainte inférieure supérieure ou égale.

Ce qui suit est juste une supposition d’une expérience. Ainsi, il réalise un constrant. Mais il essaie également de rendre le plus petit possible error dans l'interface utilisateur résultante pour l'autre contrainte non prioritaire non atteinte non atteinte. Par conséquent, la hauteur de la vue de collection sera égale à la taille de la vue parent.

82
hasan

J'ai fini par sous-classer la UICollectionView et redéfinir certaines méthodes comme suit.

  • Renvoyer self.collectionViewLayout.collectionViewContentSize pour intrinsicContentSize permet de toujours avoir la bonne taille
  • Ensuite, appelez-le chaque fois que cela peut changer (comme sur reloadData)

Code:

override func reloadData() {
    super.reloadData()
    self.invalidateIntrinsicContentSize()
}

override var intrinsicContentSize: CGSize {
    return self.collectionViewLayout.collectionViewContentSize
}

Mais sachez que vous perdez "la réutilisation de cellules", si vous affichez de grands ensembles de données, même s'ils ne tiennent pas à l'écran.  

9
d4Rk

Vous devez définir une contrainte de hauteur égale à la taille du contenu.

HeightConstraint.constant = collection.contentSize.height 
5
Bhanupriya

1) Définissez la hauteur fixe de votre CollectionView.

2) Créer un point de vente de cette constante de hauteur de CollectionView . Comme : 

IBOutlet NSLayoutConstraint * constHeight;

3) Ajoutez la méthode ci-dessous dans votre fichier .m:

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];

    CGFloat height = collectionMenu.collectionViewLayout.collectionViewContentSize.height;
    constHeight.constant = height;
}
4
Parth Patel

calculez d'abord le nombre de cellules que vous le multipliez par la hauteur de la cellule, puis retournez la hauteur dans cette méthode

    collectionView.frame = CGRectMake (x,y,w,collectionView.collectionViewLayout.collectionViewContentSize.height); //Objective C
    //[collectionView reloadData];
   collectionView.frame = CGRect(x: 0, y: 0, width: width, height: collectionView.collectionViewLayout.collectionViewContentSize.height) // Swift
1
matloob Hasnain