web-dev-qa-db-ja.com

UICollectionViewFlowLayout expectedItemSizeはiOS 11では正常に動作しますが、iOS12では正常に動作しません。*

使用するUICollectionViewの動的な高さセルの場合、

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

高さと幅の適切な制約により、iOS 11. *バージョンでは正常に動作しますが、壊れてiOS 12.0のセルが動的になりません

29
Aman Gupta

私の場合、次の制約をセルのcontentViewに明示的に追加することでこれを解決しました。

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])
    }
}

これらの制約は既にセルのxib内にありますが、どういうわけかiOS 12には十分ではありません。

さまざまな場所でcollectionView.collectionViewLayout.invalidateLayout()を呼び出すことを提案した他のスレッドは、私の状況では役に立ちませんでした。

サンプルコード: https://github.com/larrylegend/CollectionViewAutoSizingTest

これは https://medium.com/@wasinwiwongsak/uicollectionview-with-autosizing-cell-using-autolayout-in-ios-9-10-84ab5cdf35a2 によるチュートリアルのコードに回避策を適用します:

64
ale84

ale84の回答に基づき、iOS 12を複数の場所で修正する必要があるという事実のため、UICollectionViewCell + iOS12という名前のUICollectionViewCell拡張機能を作成しました。

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])
    }
}

コレクションビューのセルでは、次のようにします(セルがIBで作成されている場合):

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

上記の答えの客観的なCバージョン:

-(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]];
    }

}

私のようなObjective-C愛好家のために;)乾杯!!!

1
Harish Pathak