remy boys
remy boys

Reputation: 2958

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

Upvotes: 1

Views: 576

Answers (1)

Rikh
Rikh

Reputation: 4222

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.

Upvotes: 1

Related Questions