135 votes

Comment déterminer la hauteur de UICollectionView avec FlowLayout ?

J'ai un UICollectionView avec un UICollectionViewFlowLayout et je veux calculer la taille de son contenu (pour le retour en intrinsicContentSize nécessaire pour ajuster sa hauteur via AutoLayout).

Les problèmes sont : Même si j'ai une hauteur fixe et égale pour toutes les cellules, je ne sais pas combien de "rangées"/lignes j'ai dans le tableau de bord. UICollectionView . Je ne peux pas non plus déterminer ce nombre par le nombre d'éléments de ma source de données, puisque les cellules représentant les éléments de données varient en largeur, et donc le nombre d'éléments que j'ai dans une ligne de l'écran. UICollectionView .

Comme je n'ai pas trouvé d'indications à ce sujet dans la documentation officielle et que la recherche sur Internet ne m'a pas permis d'aller plus loin, toute aide ou idée serait très appréciée.

12voto

Cesare Points 4043

Swift 4.2

class DynamicCollectionView: UICollectionView {
    override func layoutSubviews() {
        super.layoutSubviews()
        if bounds.size != intrinsicContentSize {
            invalidateIntrinsicContentSize()
        }
    }

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

9voto

Wilson Points 6094

Swift 4

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

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

6voto

Er. Vihar Points 860

Il est trop tard pour répondre à cette question, mais j'ai récemment été confronté à ce problème.
@lee's réponse ci-dessus aidez-moi beaucoup à obtenir ma réponse. Mais cette réponse est limitée à objectif-c et je travaillais dans rapide .
En référence à votre réponse, permettez-moi de permettre à l'utilisateur de Swift de résoudre ce problème facilement. Pour cela, veuillez suivre les étapes ci-dessous :

Déclarer un CGFloat dans la section de déclaration :

var height : CGFloat!

Sur viewDidAppear vous pouvez l'obtenir par :

height = self.myCollectionView.collectionViewLayout.collectionViewContentSize().height

Peut-être que lorsque vous reload données, vous devez alors calculer une nouvelle hauteur avec de nouvelles données, vous pouvez l'obtenir par : addObserver pour écouter quand votre CollectionView fini de recharger les données à viewWillAppear :

override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(true)
        ....
        ....
        self.shapeCollectionView.addObserver(self, forKeyPath: "contentSize", options: NSKeyValueObservingOptions.Old, context: nil)
    }

Ensuite, ajoutez la fonction ci-dessous pour obtenir la nouvelle hauteur ou pour faire quoi que ce soit après. collectionview Le rechargement est terminé :

override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
        let newHeight : CGFloat = self.myCollectionView.collectionViewLayout.collectionViewContentSize().height

        var frame : CGRect! = self.myCollectionView.frame
        frame.size.height = newHeight

        self.myCollectionView.frame = frame
    }

Et n'oubliez pas d'enlever l'observateur :

override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(true)
    ....
    ....
    self.myCollectionView.removeObserver(self, forKeyPath: "contentSize")
}

J'espère que cela vous aidera à résoudre votre problème dans swift.

2voto

guozqzzu Points 404

En outre, vous feriez mieux d'appeler reloadData avant d'obtenir la hauteur :

theCollectionView.collectionViewLayout.collectionViewContentSize;

2voto

HUNG TRAN DUY Points 29

Cette réponse est basée sur @Er. Vihar. Vous pouvez facilement mettre en œuvre la solution en utilisant RxSwift.

     collectionView.rx.observe(CGSize.self , "contentSize").subscribe(onNext: { (size) in
        print("sizer \(size)")
    }).disposed(by: rx.disposeBag)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X