Reputation: 14828
Is there a way to dynamically size UICollectionViewCell
s in only one direction, like height, while making the width follow the layout's itemSize dimension? Or is it all or nothing?
Upvotes: 0
Views: 743
Reputation: 455
From iOS 8 on their is an api provided by Apple called Self-Sizing Cells, which is great and very easy to use (it does have some issues, but thoes are rather small compared to the benefits).
To use it you have to do two things:
Set up auto layout in your cell so that a height and width can be obtained from the constraints.
Simply set the estimatedItemSize property of the collection views layout object to a non-zero value:
UICollectionViewFlowLayout *collectionViewLayout = (UICollectionViewFlowLayout *)self.collectionView.collectionViewLayout;
collectionViewLayout.estimatedItemSize = //your estimated item size
That's it for self-sizing cells (for more info watch the WWDC 2014 video "What's New in Table and Collection Views")! If you want more fine grained control you will probably need to subclass UICollectionViewLayout...
Upvotes: 1
Reputation: 1908
You can create a cell for sizing purposes from NIB for example:
_sizingCell = [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass([MyCell class]) owner:self options:nil] firstObject];
Let's assume that MyCell has a titleLabel for exmpl. Then you can let the autolayout calculate the size for you in collectionView:layout: sizeForItemAtIndexPath:
NSString *title = self.items[indexPath.item];
self.sizingCell.titleLabel.text = item.title;
CGSize size = [self.sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
return CGSizeMake(size.width, 33);
This operation can take a time, so I suggest to cache the calculated value. Let's create property NSCache *cellWidthCache
NSString *title = self.items[indexPath.item];
self.sizingCell.titleLabel.text = item.title;
NSNumber *cachedWidth = [self.cellWidthCache objectForKey:indexPath];
if (!cachedWidth) {
cachedWidth = @([self.sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].width);
[self.cellWidthCache setObject:cachedWidth forKey:indexPath];
}
return CGSizeMake(cachedWidth.floatValue, 33);
Upvotes: 2