1

I put a UICollectionView into the UITableViewCell by following this tutorial and in my UICollectionViewCell, 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() {
        super.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
        collectionView.reloadData()
    }


    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.setNeedsLayout()
//        
//        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.addSubview(imageView)

         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 AutoLayout 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..

NSPratik
  • 4,714
  • 7
  • 51
  • 81
remy boys
  • 2,928
  • 5
  • 36
  • 65
  • If Collectionview resizing works tableview cell should resize it self in case you put right layouts. Collectionview do not resize itself automatically, there is internal layout system – Anton Jun 13 '16 at 13:55
  • @Anton ou mean i have to handle the layout of collectionView separately ?? – remy boys Jun 13 '16 at 13:58
  • Yes. but put laoyut for anyobject in your tableview cell, so automatic demsion should resize cell first – Anton Jun 13 '16 at 14:03
  • @Anton what you mean ? can you please elaborate ? – remy boys Jun 13 '16 at 14:06
  • UITableViewAutomaticDimension will not work with wrong cell layouts. right now it's not resizeing tebleview cell. – Anton Jun 13 '16 at 14:18

1 Answers1

1

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.

Rikh
  • 4,078
  • 3
  • 15
  • 35
  • man this collectionView thing is really Pain in the Ass , i hope your solution can work for me , can you please elaborate little bit more ?/ – remy boys Jun 13 '16 at 16:35
  • hey @IrLearn please see my this question http://stackoverflow.com/questions/37795158/crash-while-scrolling-through-the-tableview-which-haves-a-collectionview-in-it – remy boys Jun 13 '16 at 16:50
  • @remyboys, yeah sure which part? Like how to add the constraints or like calculating the height or all of it? Ill edit my answer appropriately. (Its going to be one big comment otherwise) And as far as the other question is concerned, i don't think the flow layout is causing the crash. It should show a weird UI based on your error message but i don't think it should have crashed. – Rikh Jun 13 '16 at 17:15
  • i never used UICollectionView before and dont know much about the layout api's so if you can provide a short demo or snippet of what am trying to achieve then it'll good for me @IeLearn – remy boys Jun 13 '16 at 17:18
  • 1
    There, editted the comment. That should work for you. – Rikh Jun 13 '16 at 17:43
  • thanks man , its not exactly what i was excepting but doing the job though , appreciate you – remy boys Jun 13 '16 at 18:26