【问题标题】:UICollectionViewFlowLayout not line breaking correctlyUICollectionViewFlowLayout 不能正确换行
【发布时间】:2014-01-07 20:35:14
【问题描述】:

我对流布局进行了子类化,并将其设置为我的集合视图上的collectionViewLayout

然后我设置布局如下:

- (id) init
{
    if(self = [super init])
    {
        self.minimumInteritemSpacing = 11.0;
        self.scrollDirection = UICollectionViewScrollDirectionVertical;
        self.itemSize = CGSizeMake(64.0,32.0);
        self.minimumLineSpacing = 10.0;
        self.sectionInset = UIEdgeInsetsMake(11.0,95.0,11.0,11.0);

        return self;
    }
    return nil;
}

95 + 64 + 11 + 64 + 11 + 64 + 11 = 320 - 我查过了。 (即左插图 3 个单元格 2 个空格和右插图)

我有 1 个部分,72 个项目,以及用于索引路径功能的单元格:

- (UICollectionViewCell*) collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    CustomCell *cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifierForCustomCell forIndexPath:indexPath];

    cell.mainLabel.text = [@(indexPath.item) stringValue];

    return cell;
}

输出是这样的:

如您所见,每行只有 2 个单元格。此外,它不会显示每 3 个单元格。

我看了一下流布局的布局函数产生了什么

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {

给...

这是layoutAttributes [NSArray] 中的前 3 个布局属性,如您所见,它已决定仅将前 2 项和第 4 项视为对矩形可见(320 x 568)。这一定是集合视图布局中的错误,不是吗?集合视图填满屏幕,宽度为 320。因此,由于这是一个换行布局,因此任何项目都不应该离开屏幕。

移除边缘插图:

它按预期工作。但是我想要部分插图,因为我需要添加一些装饰视图,这些视图需要在同一个滚动视图中,而我需要一个比右插图大得多的左侧插图。

【问题讨论】:

    标签: ios uikit uicollectionview


    【解决方案1】:

    Apple 的 UICollectionViewFlowLayout 中存在一个错误,其中某些单元格显示超出范围。 这些资源将帮助您修复它(您必须创建 UICollectionViewFlowLayout 的子类并覆盖此方法):

    - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
        NSArray *attributes = [super layoutAttributesForElementsInRect:rect];
        NSMutableArray *newAttributes = [NSMutableArray arrayWithCapacity:attributes.count];
        for (UICollectionViewLayoutAttributes *attribute in attributes) {
            if ((attribute.representedElementCategory != UICollectionElementCategoryCell) || // always include everything that's not a cell
                ((attribute.frame.origin.x + attribute.frame.size.width <= (self.collectionViewContentSize.width - self.sectionInset.right)) &&
                 (attribute.frame.origin.y + attribute.frame.size.height <= (self.collectionViewContentSize.height - self.sectionInset.bottom))))
            {
                [newAttributes addObject:attribute];
            }
        }
        return newAttributes;
    }
    

    此修复的基础来源:

    【讨论】:

    • 不幸的是我已经尝试过了。如果我正确阅读它,这是从绘制中删除“额外”的部分屏幕外项目。我的问题是该功能不包括应该在屏幕上显示的所有项目
    • 不,再试一次。这将解决您的问题。我有完全相同的问题。问题源于布局在某些情况下忽略了计算中的插图。然后它为单个单元格返回 2(!) 个布局属性对象,其中一个是无效的。这段代码解决了这个问题。
    • 我的属性数组打印输出(上图)是通过在该函数的“return newAttributes”行放置断点获得的。属性中有 28 项,newAttributes 中有 28 项。如果您考虑...我的问题是[超级布局...]正在跳过某些索引路径(应该显示)处的项目;实际上过滤属性数组的函数如何将那些跳过的索引路径添加回来?
    • 它按预期工作。它每行显示 4 个项目,因为 4 个项目 = 256 和 3 个空格 = 33 和 320 > (256 + 33)
    • 如果 sectionInset 为 (11,0,11,0),我附上了截图
    【解决方案2】:

    直到有人弄清楚发生了什么以及这是否是一个错误,我目前用来解决这个问题的方法是:

    - (NSArray *)alterAttributes:(NSArray *)attributes
    {
        for (UICollectionViewLayoutAttributes *attribute in attributes) {
    
            switch (attribute.indexPath.item % 3) {
                case 0:
                    attribute.center = CGPointMake(CellX1,attribute.center.y);
                    break;
                case 1:
                    attribute.center = CGPointMake(CellX2,attribute.center.y);
                    break;
                case 2:
                    attribute.center = CGPointMake(CellX3,attribute.center.y);
                    break;
    
                default:
                    break;
            }
        }
        return attributes;
    }
    

    手动更改 layoutAttributesForElementsInRect 中的 x 坐标 - 并不是一个真正令人满意的解决方案。

    【讨论】:

      猜你喜欢
      • 2020-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-10
      • 1970-01-01
      • 1970-01-01
      • 2017-04-02
      相关资源
      最近更新 更多