Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

collectionViewContentSize in iOS 10 using self-sizing cells

Prior to iOS 10, I had a self-sizing table view that solely consisted of a UICollectionView with self-sizing cells using a standard UICollectionViewFlowLayout. The collection view cells are sized using auto-layout. In order for the table cell to size itself correctly, I had to find the collection view's content size and use that within the table cell's systemLayoutSizeFittingSize:withHorizontalFittingPriority:verticalFittingPriority:.

I also found that the call to collectionView.collectionViewLayout.collectionViewContentSize used the estimatedItemSize instead of the correctly sized cell sizes unless I called collectionView layoutIfNeeded. This resulted in a systemLayoutSizeFittingSize of:

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

The call to layoutIfNeeded now causes a *** Assertion failure in -[_UIFlowLayoutSection computeLayoutInRect:forSection:invalidating:invalidationContext:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3599.6/UIFlowLayoutSupport.m:823

Am I violating some ethical rule by calling layoutIfNeeded within systemLayoutSizeFittingSize? Is there some better method to calculate a collection view's content size when it is using self-sizing cells? I would rather not have to move from auto layout to doing these size calculations in code, but that is certainly a worst case option.

like image 862
ManicJason Avatar asked Sep 14 '16 19:09

ManicJason


People also ask

Are collection view cells self-sizing in iOS?

While table view cells self-sizing has been elaborated numerous times and is widely adopted in community, the exact same feature for collection views is unjustly left unnoticed, despite being around since iOS 8. The present step-by-step guide addresses this issue by explaining how to implement self-sizing collection view cells in iOS from scratch.

How to display dynamic content with different heights in iOS 8?

Displaying dynamic content in TableView or CollectionView with cells of different heights was not an easy process before iOS 8. We used to have to calculate the height of each cell programmatically and increase the height of the respective cell. With Self-Sizing Cells, displaying dynamic content with variable heights is a simple process.

Why does my uicollectionview say “the item width must be less”?

You’ll notice numerous debugger warnings, saying that “The item width must be less than the width of the UICollectionView …“. This reveals the need to constraint cells horizontally and force them to grow in height. Enabling vertical self-sizing is a two-step process. Firstly, titleLabel need to be multi-line to support vertical growing.

What is dynamic cells sizing in uicollectionviewflowlayout?

Dynamic cells sizing is an opt-in feature of UICollectionViewFlowLayout, which could be enabled by setting estimatedItemSize property to a non-zero value. Once estimated size has been set, the flow layout computes a first approximation of cells arrangement.


1 Answers

This is some strange bug in iOS10 with iPhone Plus devices only. I've faced the same issue, my solution was to call layoutIfNeeded like this:

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

Doing the same thing in different UICollectionViewDataSources methods will work as well

like image 52
orxelm Avatar answered Sep 24 '22 08:09

orxelm