美文网首页
iOS自定义collectionViewLayout

iOS自定义collectionViewLayout

作者: bugLife丶 | 来源:发表于2020-09-09 11:00 被阅读0次

    iOS自定义collectionViewLayout

    iOS开发collectionView也算用的比较广泛了,但是系统的collectionViewLayout有时候不能够满足开发需求,比如小红书那种瀑布流。这里讲一讲自定义collectionViewLayout,需要重写四个方法

    1. -(void)prepareLayout
      2.-(CGSize)collectionViewContentSize;
      3.-(NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect;
      4.-(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath;

    直接上代码

    @interface SSCollectionViewLayout()
    
    /** cell height arrays */
    @property(nonatomic,strong)NSArray *cellHeightArrays;
    
    /** attributes arrays */
    @property(nonatomic,strong)NSMutableArray *attributesArrays;
    
    /** cell array */
    @property(nonatomic,strong)NSMutableArray *tempAttributesArrays;
    
    @end
    
    @implementation SSCollectionViewLayout
    
    -(instancetype)initWithArrays:(NSArray *)cellHeightArrays
    {
        if (self = [super init]) {
        
            self.cellHeightArrays = cellHeightArrays;
        }
    
        return self;
    }
    
    //自定义layout需要重写这些方法
    -(void)prepareLayout
    {
        [super prepareLayout];
        
        [self.attributesArrays  removeAllObjects];
        [self.tempAttributesArrays removeAllObjects];
        //获取当前collectionView对应区的item
        //获取senction全部个数
        NSInteger count = [self.collectionView numberOfItemsInSection:0];
        for (int i=0; i < count; i++) {
            UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForRow: i inSection:0]];
       
            [self.attributesArrays addObject:attributes];
        }
        
    }
    
    //返回collectionView的内容的尺寸
    -(CGSize)collectionViewContentSize
    {
        CGFloat maxContentHeight = CGRectGetMaxY([[self.tempAttributesArrays firstObject] frame]);
        for (UICollectionViewLayoutAttributes *attributes in self.tempAttributesArrays) {
            if (maxContentHeight  < attributes.frame.size.height) {
                maxContentHeight = CGRectGetMaxY(attributes.frame);
            }
        }
        return CGSizeMake(self.collectionView.bounds.size.width, maxContentHeight);
    }
    
    -(NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
    {
        return self.attributesArrays;
    }
    ///返回对应于indexPath的位置的cell的布局属性,返回指定indexPath的item的布局信息。子类必须重载该方法,该方法只能为cell提供布局信息,不能为补充视图和装饰视图提供。
    -(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
    {
        UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
        CGFloat itemWidth = (self.collectionView.bounds.size.width  - (10 + 10 + 10 * 2))/3;
        CGFloat itemHeight = [self.cellHeightArrays[indexPath.row] floatValue];
        //在这里用上cellArrays了,横排最多显示3个
        if (self.tempAttributesArrays.count < 3) {//设置第一排rect
            [self.tempAttributesArrays addObject:attributes];
            NSLog(@"%ld",self.tempAttributesArrays.count);
            CGRect rect  = CGRectMake(10 +( itemWidth + 10) * (self.tempAttributesArrays.count - 1), 10, itemWidth, itemHeight);
            attributes.frame = rect;
        }else{
            
            UICollectionViewLayoutAttributes *fristAttributes = [self.tempAttributesArrays firstObject];
            CGFloat minY = CGRectGetMaxY(fristAttributes.frame);
            CGFloat Y = minY;
            NSInteger index = 0;
            CGRect itemFrame = CGRectMake(fristAttributes.frame.origin.x, CGRectGetMaxY(fristAttributes.frame) + 10, itemWidth, itemHeight);
            for (UICollectionViewLayoutAttributes *attri in self.tempAttributesArrays) {
                if (minY > CGRectGetMaxY(attri.frame)) {
                    minY = CGRectGetMaxY(attri.frame);
                    Y = minY;
                    itemFrame = CGRectMake(attri.frame.origin.x, Y + 10, itemWidth, itemHeight);
                    NSInteger currentIndex = [self.tempAttributesArrays indexOfObject:attri];
                    index = currentIndex;
                }
            }
           
            attributes.frame = itemFrame;
            [self.tempAttributesArrays replaceObjectAtIndex:index withObject:attributes];
    
        }
       
        return attributes;
    }
    

    这里我们就实现了一个自定义layout,例子显示横屏3个item,高度通过动态传过来,实际开发中,需要跟后台商量,返回cell高度。

    相关文章

      网友评论

          本文标题:iOS自定义collectionViewLayout

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