One of our application screens requires us to place a UICollectionView
inside of a UITableViewCell
. This UICollectionView
will have a dynamic number of items, resulting in a height which must be calculated dynamically as well. However, I am running into problems trying to calculate the height of the embedded UICollectionView
.
Our overarching UIViewController
was created in Storyboards and does make use of auto layout. But, I don't know how to dynamically increase the height of the UITableViewCell
based on the height of the UICollectionView
.
Can anyone give some tips or advice on how to accomplish this?
Pablo Romeu's answer above (https://stackoverflow.com/a/33364092/2704206) helped me immensely with my issue. I had to do a few things differently, however, to get this working for my problem. First off, I didn't have to call
layoutIfNeeded()
as often. I only had to call it on thecollectionView
in thesystemLayoutSizeFitting
function.Secondly, I had auto layout constraints on my collection view in the table view cell to give it some padding. So I had to subtract the leading and trailing margins from the
targetSize.width
when setting thecollectionView.frame
's width. I also had to add the top and bottom margins to the return valueCGSize
height.To get these constraint constants, I had the option of either creating outlets to the constraints, hard-coding their constants, or looking them up by an identifier. I decided to go with the third option to make my custom table view cell class easily reusable. In the end, this was everything I needed to get it working:
As a helper function to retrieve a constraint by identifier, I add the following extension:
NOTE: You will need to set the identifier on these constraints in your storyboard, or wherever they are being created. Unless they have a 0 constant, then it doesn't matter. Also, as in Pablo's response, you will need to use
UICollectionViewFlowLayout
as the layout for your collection view. Finally, make sure you link thecollectionView
IBOutlet to your storyboard.With the custom table view cell above, I can now subclass it in any other table view cell that needs a collection view and have it implement the
UICollectionViewDelegateFlowLayout
andUICollectionViewDataSource
protocols. Hope this is helpful to someone else!Pablo's solution did not work very well for me, I had strange visual effects (the collectionView not adjusting correctly).
What worked was to adjust the height constraint of the collectionView (as a NSLayoutConstraint) to the collectionView contentSize during
layoutSubviews()
. This is the method called when autolayout is applied to the cell.Easiest approach I've came up with, so far, Credits to @igor answer above,
In your tableviewcell class just insert this
and of course, change the collectionviewoutlet with your outlet in the cell's class
I was facing the same issue recently and I almost tried every solution in the answers, some of them worked and others didn't my main concern about @PabloRomeu approach is that if you have other contents in the cell (other than the collection view) you will have to calculate their heights and the heights of their constraints and return the result to get the auto layout right and I don't like to calculate things manually in my code. So here is the solution that worked fine for me without doing any manual calculations in my code.
in the
cellForRow:atIndexPath
of the table view I do the following:I think what happens here is that I force the tableview cell to adjust its height after the collection view height has been calculated. (after providing the collectionView date to the data source)
I think, my way is much more simple, then proposed by @PabloRomeu.
Step 1. Create outlet from
UICollectionView
toUITableViewCell subclass
, whereUICollectionView
is placed. Let, it's name will becollectionView
Step 2. Add in IB for
UICollectionView
height constraint and create outlet toUITableViewCell subclass
too. Let, it's name will becollectionViewHeight
.Step 3. In
tableView:cellForRowAtIndexPath:
add code:Maybe my variant will be useful; i've been deciding this task during last two hours. I don't pretend it's 100% correct or optimal, but my skill's very small yet and i'd like to hear comments from experts. Thank you. One important note: this works for static table - it's specified by my current work. So, all I use is viewWillLayoutSubviews of tableView. And a little bit more.