33

对于我们使用的 UICollectionView 的动态高度单元格,

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

在高度和宽度的适当约束下,它适用于 iOS 11.* 版本,但它会破坏并且不会使单元格在 iOS 12.0 中动态化

4

5 回答 5

68

就我而言,我通过向单元格的 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的教程中的代码:

于 2018-09-18T14:38:13.377 回答
10

基于ale84的回答,并且由于我需要在多个地方修复 iOS 12,我创建了一个 UICollectionViewCell 扩展,我将其命名为 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])
    }
}

然后在您的集合视图单元格中,我们执行以下操作(如果您的单元格是在 IB 中创建的):

override func awakeFromNib() {
    super.awakeFromNib()
    if #available(iOS 12, *) { setupSelfSizingForiOS12(contentView: contentView) }
}
于 2018-10-03T20:22:19.103 回答
1

上述答案的目标 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 爱好者 ;) 干杯 !!!

于 2018-10-23T09:38:48.437 回答
-1

我也有同样的问题。使用 UILabels 来调整 collectionview 的大小。如果我collectionView.collectionViewLayout.invalidateLayout()在重新加载数据之前运行它可以很好地调整标签的大小。

还是不太对。我很难想象,因为我在模拟器和设备上运行它。

于 2018-08-16T11:04:13.767 回答
-1

我设法通过将这样的代码放入我的 UICollectionViewCell 子类来解决这个问题

- (UICollectionViewLayoutAttributes *)preferredLayoutAttributesFittingAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes {
    [self updateConstraintsIfNeeded];
    CGSize size = [self systemLayoutSizeFittingSize:CGSizeMake(1000, 1000)];

    CGRect alteredRect = layoutAttributes.frame;
    alteredRect.size = size;
    layoutAttributes.frame = alteredRect;
    return layoutAttributes;
}

并像这样子类化 UICollectionView

@interface CustomCollectionView ()
@property (nonatomic) BOOL shouldInvalidateLayout;
@end

@implementation CustomCollectionView

- (void)layoutSubviews {
    [super layoutSubviews];
    if (self.shouldInvalidateLayout) {
        [self.collectionViewLayout invalidateLayout];
        self.shouldInvalidateLayout = NO;
    }
}

- (void)reloadData {
    self.shouldInvalidateLayout = YES;
    [super reloadData];
}

@end
于 2018-09-24T13:27:33.917 回答