web-dev-qa-db-fra.com

UICollectionViewFlowLayout EstimatedItemSize ne fonctionne pas correctement avec iOS12 mais fonctionne correctement avec iOS 11. *

Pour les cellules de hauteur dynamiques utilisées par UICollectionView,

if let layout = self.collectionViewLayout as? UICollectionViewFlowLayout {
    layout.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize
}

avec la contrainte appropriée de hauteur et de largeur, cela fonctionne très bien avec les versions de iOS 11. * mais cela rompt et ne rend pas les cellules dynamiques pour iOS 12.0 

25
Aman Gupta

Dans mon cas, j'ai résolu ce problème en ajoutant explicitement les contraintes suivantes au contenu de la cellule.

class Cell: UICollectionViewCell {
    // ...

    override func awakeFromNib() {
        super.awakeFromNib()

        // Addresses a separate issue and prevent auto layout warnings due to the temporary width constraint in the xib.
        contentView.translatesAutoresizingMaskIntoConstraints = false

        // Code below is needed to make the self-sizing cell work when building for iOS 12 from Xcode 10.0:
        let leftConstraint = contentView.leftAnchor.constraint(equalTo: leftAnchor)
        let rightConstraint = contentView.rightAnchor.constraint(equalTo: rightAnchor)
        let topConstraint = contentView.topAnchor.constraint(equalTo: topAnchor)
        let bottomConstraint = contentView.bottomAnchor.constraint(equalTo: bottomAnchor)
        NSLayoutConstraint.activate([leftConstraint, rightConstraint, topConstraint, bottomConstraint])
    }
}

Ces contraintes sont déjà en place dans la bibliothèque xib de la cellule, mais elles ne suffisent pas pour iOS 12.

Les autres discussions qui ont suggéré d'appeler collectionView.collectionViewLayout.invalidateLayout() à différents endroits ne m'ont pas aidé. 

Exemple de code ici: https://github.com/larrylegend/CollectionViewAutoSizingTest

Ceci applique la solution de contournement au code d'un tutoriel de https://medium.com/@wasinwiwongsak/uicollectionview-with-autosizing-cell-using-autolayout-in-ios-9-10-84ab5cdf35a2

53
ale84

Sur la base de la réponse de ale84 et du fait que j'avais besoin de la correction iOS 12 à plusieurs endroits, j'ai créé une extension UICollectionViewCell que j'ai appelée UICollectionViewCell + iOS12:

extension UICollectionViewCell {
    /// This is a workaround method for self sizing collection view cells which stopped working for iOS 12
    func setupSelfSizingForiOS12(contentView: UIView) {
        contentView.translatesAutoresizingMaskIntoConstraints = false
        let leftConstraint = contentView.leftAnchor.constraint(equalTo: leftAnchor)
        let rightConstraint = contentView.rightAnchor.constraint(equalTo: rightAnchor)
        let topConstraint = contentView.topAnchor.constraint(equalTo: topAnchor)
        let bottomConstraint = contentView.bottomAnchor.constraint(equalTo: bottomAnchor)
        NSLayoutConstraint.activate([leftConstraint, rightConstraint, topConstraint, bottomConstraint])
    }
}

Et ensuite, dans les cellules de votre vue de collection, nous faisons quelque chose comme ceci (si votre cellule est créée dans IB):

override func awakeFromNib() {
    super.awakeFromNib()
    if #available(iOS 12, *) { setupSelfSizingForiOS12(contentView: contentView) }
}
6
Vasil Garov

La version Objective C de la réponse ci-dessus:

-(void)awakeFromNib{
    [super awakeFromNib];

    if (@available(iOS 12.0, *)) {
        // Addresses a separate issue and prevent auto layout warnings due to the temporary width constraint in the xib.
        self.contentView.translatesAutoresizingMaskIntoConstraints = NO;

        // Code below is needed to make the self-sizing cell work when building for iOS 12 from Xcode 10.0:

        NSLayoutConstraint *leftConstraint = [self.contentView.leftAnchor constraintEqualToAnchor:self.leftAnchor constant:0];
        NSLayoutConstraint *rightConstraint = [self.contentView.rightAnchor constraintEqualToAnchor:self.rightAnchor constant:0];
        NSLayoutConstraint *topConstraint = [self.contentView.topAnchor constraintEqualToAnchor:self.topAnchor constant:0];
        NSLayoutConstraint *bottomConstraint = [self.contentView.bottomAnchor constraintEqualToAnchor:self.bottomAnchor constant:0];

        [NSLayoutConstraint activateConstraints:@[leftConstraint, rightConstraint, topConstraint, bottomConstraint]];
    }

}

Pour les amateurs Objective-C comme moi;) Bravo !!!

0
Harish Pathak