Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically Set ContentSize of UICollectionView

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?

like image 330
jac300 Avatar asked Jul 22 '13 20:07

jac300


2 Answers

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.

like image 147
Caleb Avatar answered Oct 08 '22 08:10

Caleb


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);
}
like image 35
Sankalp S Raul Avatar answered Oct 08 '22 09:10

Sankalp S Raul