关于ios:在运行时更改集合视图单元格的宽度

Change collection view cell width at runtime

我正在创建一个EPG(电子节目指南);检索程序信息,我使用JSON。对于设计,我在左半部分有一个表格视图,用于显示频道徽标和名称,在右半部分中具有用于该频道的所有电视节目的集合视图。事实是,对于每个节目,集合视图行必须具有不同的宽度,该宽度取决于节目的持续时间。

我基于一个名为EPG Grid

的出色示例来构建它

但是在此示例中,所有通道均预先装入一个阵列中。如果通道列表很短,那么效果很好,但是在我的情况下,列表很大,因此我需要将每个通道加载到tableView:cellForRowAtIndexPath:中,然后创建具有指定宽度的布局。

对此有何想法?


这是Swift 5唯一适用于我的东西,希望对您有所帮助。

1
2
3
4
5
6
7
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator)
{
     super.viewWillTransition(to: size, with: coordinator)
           
     collectionView.collectionViewLayout.invalidateLayout()
     collectionView.frame.size = size
}

我自己弄清楚,在我的情况下,事情是不要使用UICollectionViewLayout(CustomLayout)使用布局Flow并在tableView内添加collectionView,如下所示:

enter

1
2
3
4
5
6
7
8
9
10
11
12
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;
}

委托后,调用方法collectionView:sizeForItemAtIndexPath,在此方法上,您必须使用indexPath

计算宽度或高度检索数据

1
2
3
4
5
6
7
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize
{
    //Calculation of width based on indexPath

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

最后,为了使所有单元格的滚动同时均匀,请使用方法scrollViewDidScroll。检查这篇文章:一起水平滚动UICollectionView的所有行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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;
                }
            }
        }
    }
}