web-dev-qa-db-fra.com

Redimensionner automatiquement la hauteur d'UICollectionView pour l'adapter à la taille de son contenu

J'ai un UICollectionView, un bouton qui crée une nouvelle cellule dans la vue Collection. Et je veux que UICollectionView ajuste sa taille en fonction de la taille de son contenu (lorsqu'il y a une ou deux cellules, UICollectionView est court, s'il y a beaucoup de cellules, UICollectionView est suffisamment grand).

Je sais comment obtenir la taille du contenu: 

collectionView.collectionViewLayout.collectionViewContentSize

Mais je ne sais pas où utiliser cette valeur. J'apprécierais que quelqu'un m'aide à comprendre comment faire en sorte qu'UICollectionView ajuste automatiquement sa hauteur.

UPD: J'ai publié sur GitHub un projet de démonstration décrivant le problème: https://github.com/avokin/PostViewer

21
AVokin

Je ne pense pas que la taille du contenu soit ce que vous recherchez. Je pense que vous souhaitez ajuster la quantité d’écran utilisée par la vue Collection, non? Cela va nécessiter un ajustement du cadre. La taille du contenu comprend la zone hors écran (défilement) ainsi que la vue à l'écran.

Je ne connais rien qui vous empêcherait de changer la taille du cadre à la volée:

collectionView.frame = CGRectMake (x,y,w,h);
[collectionView reloadData];

Si je vous comprends bien.

6

Utilisez une contrainte de hauteur pour la vue de collection et mettez à jour sa valeur avec la hauteur du contenu si nécessaire. Voir cette réponse: https://stackoverflow.com/a/20829728/3414722

6
sammalfix

Étapes pour modifier le cadre UICollectionView:

  1. Définissez la propriété "translatesAutoresizingMaskIntoConstraints" sur YES pour la vue d'ensemble de collectioview (Si vous utilisez AUTOLAYOUT).

  2. Puis mettez à jour le cadre de collectioview en tant que:

    collectionView.frame = CGRectMake (x,y,w,h);
    [collectionView reloadData];
    
0
Shahul Hasan

Vous devez contraindre la hauteur de la vue de collection à la hauteur de votre contenu:

J'utilise SnapKit dans le code suivant.

Commencez par limiter les contours de la vue de collection à son aperçu:

private func constrainViews() {
    collectionView?.translatesAutoresizingMaskIntoConstraints = true

    collectionView?.snp.makeConstraints { make in
        make.edges.equalToSuperview()
        heightConstraint = make.height.equalTo(0).constraint
    }
}

Ensuite, calculez la hauteur et définissez la hauteur sur le décalage de contrainte de hauteur. Je laisse la mise en page en flux effectuer le travail, puis je calcule la hauteur en fonction du bord inférieur du dernier attribut de mise en page:

override func viewDidLayoutSubviews() {
    guard
        let collectionView = collectionView,
        let layout = collectionViewLayout as? UICollectionViewFlowLayout
    else {
        return
    }

    let sectionInset = layout.sectionInset
    let contentInset = collectionView.contentInset

    let indexPath = IndexPath(item: tags.count, section: 0)
    guard let attr = collectionViewLayout.layoutAttributesForItem(at: indexPath) else {
        return
    }

    // Note sectionInset.top is already included in the frame's Origin
    let totalHeight = attr.frame.Origin.y + attr.frame.size.height
        + contentInset.top + contentInset.bottom
        + sectionInset.bottom

    heightConstraint?.update(offset: totalHeight)
}

Notez que dans l'exemple, j'ai toujours une balise spéciale qui n'est pas incluse dans mes éléments tags count, donc la ligne:

let indexPath = IndexPath(item: tags.count, section: 0)

devrait être quelque chose comme if items.count > 0 ... let indexPath = IndexPath(item: tags.count - 1, section: 0) dans la plupart des autres codes.

0
emp