I have a UICollectionView
that has been created programatically. Upon creation of the collection view, I would like to dynamically define the collection view height based on the number of cells that it must hold. I do not want to enable scrolling of the collection view itself, rather this collection view is being added as a subview to a view that is contained inside a vertical UIScrollView
.
For example, if the UICollectionView
has 10 UICollectionViewCells
. It might have a height of 200.0f, but if it has 20 cells it might have a height of 300.0f, and so on.
I have attempted to accomplish this by following the Apple docs here, overriding the collectionViewContentSize
method.
Although this method does return a valid CGSize
when it is called, when I instantiate the collection view, its frame
is always set to zero.
Here is what I have done so far:
//subclass UICollectionViewFlowLayout
@interface LabelLayout : UICollectionViewFlowLayout
@property (nonatomic, assign) NSInteger cellCount;
@property (nonatomic) UIEdgeInsets sectionInset;
@property (nonatomic) CGSize itemSize;
@property (nonatomic) CGFloat minimumLineSpacing;
@property (nonatomic) CGFloat minimumInteritemSpacing;
@end
- (id)init
{
self = [super init];
if (self) {
[self setup];
}
return self;
}
-(void)prepareLayout
{
[super prepareLayout];
_cellCount = [[self collectionView] numberOfItemsInSection:0];
}
- (void)setup
{
self.sectionInset = UIEdgeInsetsMake(10.0f, 0.0f, 10.0f, 0.0f);
self.itemSize = CGSizeMake(245.0f, 45.0f);
self.minimumLineSpacing = 10.0f;
self.minimumInteritemSpacing = 20.0f;
}
- (CGSize)collectionViewContentSize
{
CGFloat collectionViewWidth = 550;
CGFloat topMargin = 10;
CGFloat bottomMargin = 10;
CGFloat collectionViewHeight = (self.cellCount * (self.itemSize.height +
self.minimumLineSpacing*2)) + topMargin + bottomMargin;
//THIS RETURNS A VALID, REASONABLE SIZE, but the collection view frame never gets set with it!
return CGSizeMake(collectionViewWidth, collectionViewHeight);
}
//create collectionView in viewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self makeLabels]; //determines the number of cells
LabelLayout *layout = [[LabelLayout alloc]init];
self.collectionView = [[UICollectionView alloc]initWithFrame:CGRectZero collectionViewLayout:layout];
self.collectionView.backgroundColor = [UIColor redColor];
self.collectionView.dataSource = self;
self.collectionView.delegate = self;
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:cellIdentifier];
[self.collectionView reloadData];
[self.view addSubview:self.collectionView];
}
Additionally, when I explicitly define a static frame for the UIcollectionView
, it is created as expected, so I know that my only issue is in using the collectionViewContentSize
method.
So my question is, how can I dynamically set the height of my UICollectionView
?
A collection view is a scroll view, so your -collectionViewContentSize
method is determining the size of the content, not the size of the overall view. You'll need to set the collection view's bounds
or frame
property to set the size of the collection view itself.
You might also want to set it's scrollEnabled
property to NO
while you're at it.
Use the sizeForItemAtIndexPath:
method.
In Swift:
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize{
return CGSizeMake(250, 150);
}
In Objective-C:
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
return CGSizeMake(250, 150);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With