美文网首页ios 知识点iOSiOS
横向多行的UICollectionViewFlowLayout

横向多行的UICollectionViewFlowLayout

作者: abche | 来源:发表于2018-01-18 20:18 被阅读2233次

    需求

    需求

    页面显示最少0行最多两行,超过两行水平方向分页显示。

    效果

    collectionViewGIF.gif

    分析

    常用功能中应用个数是不固定的,高度也是不固定的,过多时横向分页。

    选择UICollectionView控件来实现,使用UICollectionViewFlowLayout布局,设置滚动方向为水平。

    问题

    使用UICollectionViewFlowLayout进行布局后发现页面显示为

    错误布局

    而我们期望的是

    正确布局

    解决方法

    核心代码

    - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
        NSInteger item = indexPath.item;
    
        /*
         0 2 4 ---\  0 1 2
         1 3 5 ---/  3 4 5 计算转换后对应的item  原来'4'的item为4,转换后为3
         */
        NSInteger page = item / (self.itemCountPerRow * self.maxRowCount);
        // 计算目标item的位置 x 横向偏移  y 竖向偏移
        NSUInteger x = item % self.itemCountPerRow + page * self.itemCountPerRow;
        NSUInteger y = item / self.itemCountPerRow - page * self.rowCount;
        // 根据偏移量计算item
        NSInteger newItem = x * self.rowCount + y;
        NSIndexPath *newIndexPath = [NSIndexPath indexPathForItem:newItem inSection:indexPath.section];
    
        UICollectionViewLayoutAttributes *newAttributes = [super layoutAttributesForItemAtIndexPath:newIndexPath];
        newAttributes.indexPath = indexPath;
    
        return newAttributes;
    }
    

    UICollectionViewLayoutAttributes是管理collectionView中item的布局相关属性的布局对象。

    我们这里通过重新设置Item对应UICollectionViewLayoutAttributes的indexPath来达到我们想要的效果,需要注意的是为了防止出现数组越界的情况这里做了使每一行Item都是“满”的处理(即Item的个数为itemCountPerRow的整数倍)。

    - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
        NSInteger itemCount;
        if (self.dataArray.count == 0) {
            itemCount = 0;
        } else if (self.dataArray.count / (kMaxRowCount * kItemCountPerRow) > 1) {
            itemCount = kMaxRowCount * kItemCountPerRow * ceilf(self.dataArray.count / (kMaxRowCount * kItemCountPerRow));
        } else {
            itemCount = ceilf(self.dataArray.count / kItemCountPerRow) * kItemCountPerRow;
        }
        return itemCount;
    }
    
    占位

    为了更好的体现,这里未对label背景颜色进行透明处理,我们可以从图中看出6、7的位置实际是返回了UICollectionViewCell。

    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
        CollectionViewLabelCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:[CollectionViewLabelCell description] forIndexPath:indexPath];
        
        if (indexPath.item < self.dataArray.count) {
            cell.backgroundColor = [UIColor lightGrayColor];
            cell.labelTitle.text = self.dataArray[indexPath.item];
        }else{
            cell.backgroundColor = [UIColor clearColor];
            cell.labelTitle.text = @"";
        }
        return cell;
    }
    

    demo地址:https://github.com/ABChe/HorizontallyPageableFlowLayout

    相关文章

      网友评论

        本文标题:横向多行的UICollectionViewFlowLayout

        本文链接:https://www.haomeiwen.com/subject/mxfgoxtx.html