12

How can I change the size of a UICollectionViewCell based on the size of its subviews, using Auto Layout?

My UICollectionViewCells each only have one view in their contentView. This is a custom UIView subclass of mine that automatically resizes itself to fit all its subviews using Auto Layout. It also implements -intrinsicContentSize correctly. However the UICollectionView, or rather its layout, do not seem to care about this.

I am using a UICollectionViewFlowLayout, and tried:

  • Leaving the itemSize at its default value. This gives me cells with a size of 50 x 50.
  • Implementing the delegate method -collectionView:layout:sizeForItemAtIndexPath:. However, when this method gets called, the cells (obviously) have not appeared on screen yet, and have not been updated by the Auto Layout system.

Is there any way to change my cells' size based on their subviews using the standard Apple classes? Or do I have to implement my own UICollectionViewLayout subclass, or something else?

fabian789
  • 8,348
  • 4
  • 45
  • 91
  • Same principle as http://stackoverflow.com/questions/18477220/have-uitableviewcell-resize-itself-with-autolayout/18481179#18481179 , you need to give the size up front, unfortunately. – jrturton Aug 30 '13 at 07:46
  • 1
    The above author has a comment there on using a "free" cell - one you create and then keep around, to populate and then get the size of. You should be able to use [cell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize] - I'm having problems now but one of these should work. – David H Oct 07 '13 at 19:24

3 Answers3

1

Have you tried this :

[self.view layoutIfNeeded];
[UIView animateWithDuration:0.5 animations:^{
     constraintConstantForWidth.constant = subviews.size.width;
     constraintConstantForHeight.constant = subviews.size.height;
     [self.view layoutIfNeeded];
}];

and make the priority of the constraint (low = 250)

I think that this issue we can handle by the constraint constant replacement.

jscs
  • 63,694
  • 13
  • 151
  • 195
Akshar Darji
  • 397
  • 2
  • 12
0

I used

- (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath {

    if (indexPath.row == 0) {
        UIButton *button = (UIButton *)[cell viewWithTag:2];
        CGRect frame = cell.frame;
        frame.size.width = button.frame.size.width;
        cell.frame = frame;
    }

}

and was able to resize my cell based on the width of the button subview in a little test app.

Make sure that the tags on your subviews are greater than 0 because if you use 0, it just gives you back the contentView. Other than that, this should get you there

MoMo
  • 499
  • 3
  • 12
-2

Try collectionView:layout:sizeForItemAtIndexPath:

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
     return self.view.frame.size;
}
banumelody
  • 21
  • 3