remy boys remy boys - 1 year ago 206
iOS Question

tableview's Row height is not changing , CollectionView is capturing all the unused space instead of resizing itself in the tableViewCell

I put a UICollectionView into the

by following this tutorial and in my
, there's a Image View. So when I run my app, the collection view is not resizing itself at the same time in my cell I put a Text View which is resizing itself according to content, see the below images:

In this first image, I have a text view at the top which have some text in it, and below it with (pink background) is my collection view and inside of that with greenBackground is my image view, as you can see that collection view is taking the extra space instead of reducing itself as Text View Did.
enter image description here

in this second image you can see that my textView haves more content then before so its resized itself now overlapping the CollectionView

enter image description here

this is my TableViewCell:

class TableViewCell: UITableViewCell {

@IBOutlet var txtView: UITextView!
@IBOutlet private weak var collectionView: UICollectionView!

override func awakeFromNib() {
// Initialization code

// collectionView.frame = self.bounds;
// collectionView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]

override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)

// Configure the view for the selected state

func setCollectionViewDataSourceDelegate
<D: protocol<UICollectionViewDataSource, UICollectionViewDelegate>>
(dataSourceDelegate: D, forRow row: Int) {

collectionView.delegate = dataSourceDelegate
collectionView.dataSource = dataSourceDelegate
collectionView.tag = row

var collectionViewOffset: CGFloat {
get {
return collectionView.contentOffset.x

set {

collectionView.contentOffset.x = newValue



this is my collectionViewCell

class CollectionViewCell: UICollectionViewCell {

@IBOutlet var imgView: UIImageView!

override func awakeFromNib() {

// self.contentView.frame = self.bounds;
// self.contentView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]



and this is my TableviewController

// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1

override func tableView(tableView: UITableView,
numberOfRowsInSection section: Int) -> Int {
return imageModel.count

override func tableView(tableView: UITableView,
cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

let cell = tableView.dequeueReusableCellWithIdentifier("Cell",
forIndexPath: indexPath) as! TableViewCell

cell.txtView.text = txtArray[indexPath.row]

return cell

override func tableView(tableView: UITableView,
willDisplayCell cell: UITableViewCell,
forRowAtIndexPath indexPath: NSIndexPath) {

guard let tableViewCell = cell as? TableViewCell else { return }

tableViewCell.setCollectionViewDataSourceDelegate(self, forRow: indexPath.row)

tableViewCell.collectionViewOffset = storedOffsets[indexPath.row] ?? 0


override func tableView(tableView: UITableView,
didEndDisplayingCell cell: UITableViewCell,
forRowAtIndexPath indexPath: NSIndexPath) {

guard let tableViewCell = cell as? TableViewCell else { return }

storedOffsets[indexPath.row] = tableViewCell.collectionViewOffset


extension TableViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int {

return imageModel[collectionView.tag].count

func collectionView(collectionView: UICollectionView,
cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell",
forIndexPath: indexPath) as! CollectionViewCell

cell.imgView.frame = CGRectMake(0, 0, collectionView.frame.width, collectionView.frame.height)

cell.imgView.contentMode = .ScaleAspectFit


cell.imgView.image = ResizeImage(UIImage(named: imageModel[collectionView.tag][indexPath.item])!, targetSize: CGSizeMake( cell.imgView.frame.width , cell.imgView.frame.height))
//imageView.image = UIImage(named: imageModel[collectionView.tag][indexPath.item])

return cell


How can I make this collection view to
itself according to the content in it? I also tried this:

self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 100;

but didn't worked (my collection view got disappear) if anybody knows how to do this, then please guide me..

Answer Source

I faced a similar issue when i used collection view inside a table view cell. No matter what i did i couldn't get the table view to resize automatically but the collection view did. Soo instead of autolayout i did it using code.

I ended up having to calculate the size of the label in the collection view numberOfSections in collection view and passing this height using a delegate to the view controller that has the tableView's delegate and dataSource and reloading the appropriate row of the table view.

As it happens, the numberOfSections in collectionview data source gets called everytime and the delegate resizes the table view height. Some thing like this-

-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{

    [self.delegate setViewHeight:[self getHeightForCellAtIndexPath:[NSIndexPath indexPathForRow:currentSelected inSection:0]]];

    return 1;

This ought to give you a general idea.

EDIT: Sorry i misunderstood, your question before. Here is something that should work for you:

As per my understanding, you have a table view cell with a label view and collection view inside of it.

Now, inside your table view cell, you should add top, leading and trailing constraints space to the label. Now inside your collection view position your image vertically in the center and add an appropriate top and bottom to the cell superview. Your collection view itself should have a CONSTANT value in leading, trailing, top to label and bottom to superview. Also add a fixed height constraint to your collection View (assuming you want the image sizes to remain the same).

Now lets says View Controller A is the data source for your table view and the table view cell is the data source for your collection view.

In your viewController A, you should write your height for row at indexPath as-

 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    CGSize stringSize = [yourStringArray[indexPath.row] boundingRectWithSize:CGSizeMake(_yourCollectionView.frame.size.width, FLT_MAX)
                                                  options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading)
                                               attributes:@{NSFontAttributeName:[UIFont yourFont size:yourFontSize]} context:nil].

    return stringSize.height + 35; //magic number 35, play around with it to suit your need. Did this to always have a minimum fixed height.

This will allow your tableViewRowForHeight for that particular index to have the height of your label added to it and the constraints ought to do the rest.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download