Change collection view cell width at runtime

2019-05-26 13:24发布

问题:

I'm creating an EPG (Electronic Program Guide); to retrieve the program info I use JSON. For the design, I have a table view in the left half for the channel logo and name, and in the right half a collection view for all the TV programs for that channel. The thing is that for every show the collection view row must have a different width that depends on the duration of the show.

I'm building it based on this fantastic example called: EPG Grid

But in this example, all the channels are loaded previously in one array. This works fine if the channels list is short, but in my case the list is very large, so I need to load every channel in tableView:cellForRowAtIndexPath:, then create the layout with the specified width.

Any thoughts about this?

回答1:

I figured out by my self, the thing is in my case not to use UICollectionViewLayout (CustomLayout) use layout Flow and add the collectionView inside tableView like this:

Then in every row of tableView delegate the collectionView.

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
{        
    let cell: CustomTableViewCell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CustomTableViewCell

    cell.collectionView.delegate = self
    cell.collectionView.dataSource = self
    cell.collectionView.tag = indexPath.row

    cell.tag = 100 + indexPath.row;

    return cell;
}

After delegate, the method collectionView:sizeForItemAtIndexPath is called, on this method you must to calculate width or height retrieving data using indexPath

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize 
{
    //Calculation of width based on indexPath

    //...
    return CGSizeMake(width, 89)
}

Finally for making the scroll uniform for all the cells at the same time use the method scrollViewDidScroll. Check this post: Horizontally scroll ALL rows of UICollectionView together

func scrollViewDidScroll(scrollView: UIScrollView) {

    var ret: Bool = false;

    if (self.lastContentOffset > scrollView.contentOffset.x)
    {
        ret = true;
    }
    else if (self.lastContentOffset < scrollView.contentOffset.x)
    {
        ret = true;
    }        

    if(scrollView.isKindOfClass(UICollectionView) && ret)
    {
        self.lastContentOffset = scrollView.contentOffset.x;
        for var i = 0; i < data.count; i++
        {
            let cell = self.view.viewWithTag(100 + i) as? ChannelTableViewCell;

            if(cell != nil)
            {
                let collectionCell: UICollectionView? = cell?.collectionView;

                if(collectionCell != nil)
                {
                    collectionCell!.contentOffset = scrollView.contentOffset;
                }
            }
        }
    }
}