iOS 10中的collectionViewContentSize使用自调整单元格

时间:2016-09-14 19:45:47

标签: ios objective-c uicollectionview ios10

在iOS 10之前,我有一个自我调整表视图,它只包含一个UICollectionView,其中包含使用标准UICollectionViewFlowLayout的自调整单元格。使用自动布局调整集合视图单元格的大小。为了使表格单元格能够正确调整大小,我必须找到集合视图的内容大小,并在表格单元格的systemLayoutSizeFittingSize中使用它:withHorizo​​ntalFittingPriority:verticalFittingPriority:。

我还发现对collectionView.collectionViewLayout.collectionViewContentSize的调用使用了estimatedItemSize而不是正确大小的单元格大小,除非我调用了collectionView layoutIfNeeded。这导致systemLayoutSizeFittingSize:

- (CGSize) systemLayoutSizeFittingSize:(CGSize)targetSize withHorizontalFittingPriority:(UILayoutPriority)horizontalFittingPriority verticalFittingPriority:(UILayoutPriority)verticalFittingPriority
{
    self.collectionView.frame = CGRectMake(0, 0, targetSize.width, FLT_MAX);
    [self.collectionView layoutIfNeeded];

    CGSize collectionViewContentSize = self.collectionView.collectionViewLayout.collectionViewContentSize;
    CGFloat verticalPadding = fabs(self.collectionViewTopPaddingConstraint.constant) + fabs(self.collectionViewBottomPaddingConstraint.constant);
    CGSize cellSize = CGSizeMake(collectionViewContentSize.width, collectionViewContentSize.height + verticalPadding);

    return cellSize;
}

现在调用layoutIfNeeded会导致*** Assertion failure in -[_UIFlowLayoutSection computeLayoutInRect:forSection:invalidating:invalidationContext:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3599.6/UIFlowLayoutSupport.m:823

我是否通过在systemLayoutSizeFittingSize中调用layoutIfNeeded来违反某些道德规则?在使用自定义单元格时,是否有更好的方法来计算集合视图的内容大小?我宁愿不必从自动布局转到在代码中进行这些大小计算,但这肯定是最糟糕的选择。

4 个答案:

答案 0 :(得分:16)

这是iOS10中仅有iPhone Plus设备的一些奇怪错误。我遇到了同样的问题,我的解决办法就是这样打layoutIfNeeded

func numberOfSections(in collectionView: UICollectionView) -> Int {
    collectionView.layoutIfNeeded() // Patch: only to solve UIKit crash on Plus models
    return 1
}

在不同的UICollectionViewDataSources方法中执行相同的操作也可以正常工作

答案 1 :(得分:1)

在iOS 10上开发我的应用程序时遇到同样的问题。删除第一行解决了我的问题。

self.collectionView.frame = CGRectMake(0, 0, targetSize.width, FLT_MAX); //Remove this

希望这有帮助!

答案 2 :(得分:1)

就我而言,在布局之前调用invalidateLayout是此问题的解决方法。

UIViewController子类中:

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()
    collectionView.collectionViewLayout.invalidateLayout()
}

或在UIView子类中:

override func layoutSubviews() {
    super.layoutSubviews()
    collectionView.collectionViewLayout.invalidateLayout()
}

答案 3 :(得分:0)

我在iOS 10上开发我的应用时遇到同样的问题,并在UICollectionViewDataSource上将awakeFromNib设置为自己,如下所示:

override func awakeFromNib() {
    super.awakeFromNib()
    let layout = UICollectionViewFlowLayout()
    // set your layout 
    collectionViewLayout = layout
    // set dataSource equal to self in here cause a crash
    dataSource = self
}

然后我将UICollectionViewDataSource设置代码移到layoutSubviews,问题解决了,就像这样:

override func layoutSubviews() {
        super.layoutSubviews()
        dataSource = self
    }

override func awakeFromNib() {
    super.awakeFromNib()
    let layout = UICollectionViewFlowLayout()
    // set your layout 
    collectionViewLayout = layout
    // set dataSource equal to self in here cause a crash
    dataSource = self
}

希望这有帮助!