8
votes

I have a UICollectionView, where one of my UICollectionViewCells contains a UITextView. My goal is to autosize the UICollectionViewCell to fit the content of the text view.

I have overridden collectionView:sizeForItemAtIndexPath, but I'm struggling to get at the content height value for the text view without creating an infinite loop.

Typically to autosize a UITextView, I would do something like the following:

CGRect frame = textView.frame;
frame.size.height = textView.contentSize.height;
textView.frame = frame;

But to do that within sizeForItemAtIndexPath, I need a pointer to the UITextView. To get that pointer, I find myself calling cellForItemAtIndexPath, but since that calls sizeForItemAtIndexPath it's an infinite loop.

I suspect I'm missing a way to pre-size the view and have the UICollectionView just respect that, but it appears to default to the 50x50 value that UICollectionViewFlowLayout defines.

Other (hack) ideas that I'm loathe to do:

  • Have another hidden UITextView that I can load the content into and get it's height.
  • Implement equivalent logic to calculate the content height on my own.

Thanks!

1

1 Answers

4
votes

You could set the collection view's delegate to also be the text view's delegate, and in textViewDidChange: update a property holding an up-to-date height calculated from the textView.textContainer and textView.textContainerInset. Then you simply reference this property in sizeForItemAtIndexPath:. In this case you'd also want to do some type of reloading of the cell and possibly layout invalidation every time the value of that property is about to change.