54

I have a simple UICollectionView with cells that have a single UITextView. The UITextView is constrained to the edges of the cell, so they should stay the same size as the cell size.

The problem I'm having is that for some reason these constraints are not working when I specify the cell size via collectionView:layout:sizeForItemAtIndexPath:.

I have the cell size set to 320x50 in the Storyboard. If I return a size with 2 times the height of the cell size with sizeForItemAtIndexPath:, the UITextView stays the same height despite the constraints I set. I am using Xcode 6 GM.

My view controller code is:

@implementation TestViewController - (void)viewDidLoad { [super viewDidLoad]; self.collectionView.delegate = self; self.collectionView.dataSource = self; } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; UICollectionViewCell *c = [self.collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]]; NSLog(@"%f", c.frame.size.height); UITextView *tv = (UITextView *)[c viewWithTag:9]; NSLog(@"%f", tv.frame.size.height); } - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return 1; } - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath]; return cell; } - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { UICollectionViewFlowLayout *flowLayout = (UICollectionViewFlowLayout *)collectionView.collectionViewLayout; CGSize size = flowLayout.itemSize; size.height = size.height * 2; return size; } @end 

Those logs in viewDidAppear: give me an output of:
100.00000
50.00000
As you can see, the UITextView height doesn't change with the cell height.


Here's a screenshot of the storyboard I set up with a UITextView constrained in the UICollectionViewCell:

enter image description here

I know using auto layout constraints works fine with UITableViewCells and dynamic resizing. I have no idea why it's not working in this case. Does anyone have any ideas?

4 Answers 4

111

Well, I just looked on the iOS developer forums. Apparently, this is a bug with the iOS 8 SDK running on iOS 7 devices. The workaround is to add the following to your subclass of UICollectionViewCell:

- (void)setBounds:(CGRect)bounds { [super setBounds:bounds]; self.contentView.frame = bounds; } 
override var bounds: CGRect { didSet { contentView.frame = bounds } } 
Sign up to request clarification or add additional context in comments.

7 Comments

Great ! you save my day ! this solution working for me after installing iOS 8 xcode 6 etc. all my tableview didn't adapt the uicollectionview cell size. Thank you :)
in case it didn't work for you try this: awakerFromNib(){ contentView.autoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight }
I had same issue on iPad with iOS 8, and this solution fixed the problem as well. Thanks!
+1 on this being an issue in iOS 8 too. I had a collection view cell that was working fine in iOS 7, but not in iOS 8. This fixed it.
Totally forgot about this. Thanks...still an issue with latest iOS 8 SDK running on iOS 7 devices.
|
41

Equivalent Swift Code :

override var bounds: CGRect { didSet { contentView.frame = bounds } } 

2 Comments

This answer is helpful, but is simply a translation of the accepted answer. That's probably what the person who down voted this answer thought.
Thanks, I'm using iOS 10 with a custom UICollectionViewLayout where I calculate the cell size. Autolayout wasn't working and this fixed it
24

Here is the solution, if you are not subclassing UICollectionViewCell. Just add this two lines under your cellForItemAtIndexPath: after dequeueReusableCellWithReuseIdentifier:

Obj-C

[[cell contentView] setFrame:[cell bounds]]; [[cell contentView] setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight]; 

Swift - 2.0

cell.contentView.frame = cell.bounds cell.contentView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight] 

2 Comments

For me it worked without adding second line from the code
If your app suports multiple orientation, then u will need second line also. :-) @Teena nath Paul
3

Swift 2.0:

cell.contentView.frame = cell.bounds cell.contentView.autoresizingMask = [UIViewAutoresizing.FlexibleWidth, UIViewAutoresizing.FlexibleHeight] 

1 Comment

Added this to cellForItemAtand nothing changed :(

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.