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.
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
I got same issue when develop my app on iOS 10. Remove the first line solved my problem.
self.collectionView.frame = CGRectMake(0, 0, targetSize.width, FLT_MAX); //Remove this
Hope this help!
In my case, calling invalidateLayout before layout is a workaround for this issue.
In a UIViewController subclass:
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
collectionView.collectionViewLayout.invalidateLayout()
}
or in a UIView subclass:
override func layoutSubviews() {
super.layoutSubviews()
collectionView.collectionViewLayout.invalidateLayout()
}
I got same issue when develop my app on iOS 10 and set UICollectionViewDataSource to itself on awakeFromNib,like this:
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
}
then I move the UICollectionViewDataSource setting code to layoutSubviews,the problem solved,like this:
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
}
Hope this help!
来源:https://stackoverflow.com/questions/39498503/collectionviewcontentsize-in-ios-10-using-self-sizing-cells