Since iOS 8 [UIColletionViewCell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]
returns a size with height of 0.
Here\'s what the code
This is not a bug, I have been grappling with this issue now for some time and have tried different things, I am giving below the steps that's worked for me:
1) use contentView [sampleCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
2) you can create your own contentView and have the subViews added to the contentView, don't forget to pin the top, bottom and left and right of the contentView if you are using a custom contentView to the superView, if you don't do this then height will be 0, here also depending upon your requirements you can for. e.g not pin the bottom of the contentView to the superView so that the height of the view can vary, but pinning is important and pinning which one depends on your requirements.
3) set the constraints properly in interface builder depending upon your requirements, there are certain constraints that cannot be added in interface builder, but then you can add them in viewDidLoad of the viewController.
So my 2 cents input is that constraints have to be set properly in the interface builder for systemLayoutSizeFittingSize:UILayoutFittingCompressedSize to return correct dimensions, this is the solution guys.
We're using a work-around for now, copied below. Hopefully, these issues will be resolved before iOS 8 release and we can remove this. (The kludge assumes knowledge of Apple's implicit contentView behavior, and we have to hack IB outlet references to any constraints we transfer.)
We notice they're also removing all autoresizingMasks from storyboards/NIBs during upgrade, which makes sense given it's supposed to be auto-layout, but collection views still throwback to springs & struts. Perhaps this has been overlooked in the purge?
--Dan
/**
Kludge around cell sizing issues for iOS 8 and deployment to iOS 7 when compiled for 8. Call this on the collection view cell before it is used, such as in awakeFromNib. Because this manipulates top-level constraints, any references to such initial constraints, such as from IB outlets, will be invalidated.
Issue 1: As of iOS 8 Beta 5, systemLayoutSizeFittingSize returns height 0 for a UICollectionViewCell. In IB, cells have an implicit contentView, below which views placed in IB as subviews of the cell are actually placed. However, constraints set between these subviews and its superview are placed on the cell, rather than the contentView (which is their actual superview). This should be OK, as a constraint among items may be placed on any common ancestor of those items, but this is not playing nice with systemLayoutSizeFittingSize. Transferring those constraints to be on the contentView seems to fix the issue.
Issue 2: In iOS 7, prior to compiling against iOS 8, the resizing mask of the content view was being set by iOS to width+height. When running on iOS 7 compiled against iOS 8 Beta 5, the resizing mask is None, resulting in constraints effecting springs for the right/bottom margins. Though this starts out the contentView the same size as the cell, changing the cell size, as we do in the revealing list, is not tracked by changing it's content view. Restore the previous behavior.
Moving to dynamic cell sizing in iOS 8 may circumvent this issue, but that remedy isn't available in iOS 7.
*/
+ (void)kludgeAroundIOS8CollectionViewCellSizingIssues:(UICollectionViewCell *)cell {
// transfer constraints involving descendants on cell to contentView
UIView *contentView = cell.contentView;
NSArray *cellConstraints = [cell constraints];
for (NSLayoutConstraint *cellConstraint in cellConstraints) {
if (cellConstraint.firstItem == cell && cellConstraint.secondItem) {
NSLayoutConstraint *parallelConstraint = [NSLayoutConstraint constraintWithItem:contentView attribute:cellConstraint.firstAttribute relatedBy:cellConstraint.relation toItem:cellConstraint.secondItem attribute:cellConstraint.secondAttribute multiplier:cellConstraint.multiplier constant:cellConstraint.constant];
parallelConstraint.priority = cellConstraint.priority;
[cell removeConstraint:cellConstraint];
[contentView addConstraint:parallelConstraint];
} else if (cellConstraint.secondItem == cell && cellConstraint.firstItem) {
NSLayoutConstraint *parallelConstraint = [NSLayoutConstraint constraintWithItem:cellConstraint.firstItem attribute:cellConstraint.firstAttribute relatedBy:cellConstraint.relation toItem:contentView attribute:cellConstraint.secondAttribute multiplier:cellConstraint.multiplier constant:cellConstraint.constant];
parallelConstraint.priority = cellConstraint.priority;
[cell removeConstraint:cellConstraint];
[contentView addConstraint:parallelConstraint];
}
}
// restore auto-resizing mask to iOS 7 behavior
contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[cell setNeedsUpdateConstraints];
[cell updateConstraintsIfNeeded];
}