美文网首页
UICollectionViewLayout 自定义

UICollectionViewLayout 自定义

作者: d20cdad48d2e | 来源:发表于2018-12-05 15:39 被阅读8次
    //
    //  PGGridLayout.m
    //  TestCollectionView
    //
    //  Created by Yang Li on 2018/12/5.
    //  Copyright © 2018 Qiekj. All rights reserved.
    //
    
    #import "PGGridLayout.h"
    
    @interface PGGridLayout ()
    
    @property(nonatomic, strong)NSArray *layoutInfoArray;
    @property(nonatomic, assign)CGSize contentSize;
    
    @end
    
    @implementation PGGridLayout
    
    - (instancetype)init {
        if (self = [super init]) {
            self.cellSpacing = 10;
            self.lineSpacing = 10;
            self.itemSize = CGSizeMake(100, 100);
        }
        return self;
    }
    
    - (void)setItemSize:(CGSize)itemSize {
        _itemSize = itemSize;
        [self invalidateLayout];
    }
    
    - (void)setLineSpacing:(CGFloat)lineSpacing {
        _lineSpacing = lineSpacing;
        [self invalidateLayout];
    }
    
    - (void)setCellSpacing:(CGFloat)cellSpacing {
        _cellSpacing = cellSpacing;
        [self invalidateLayout];
    }
    
    /**
     prepareLayout是专门用来准备布局的,
     在 prepareLayout 方法里面我们可以事先就计算后面要用到的布局信息并存储起来,
     防止后面方法多次计算,提高性能。例如,我们可以在此方法就计算好每个cell的属性、整个CollectionView的内容尺寸等等。
     此方法在布局之前会调用一次,之后只有在调用 invalidateLayout 、 shouldInvalidateLayoutForBoundsChange:
     返回 YES 和 UICollectionView刷新 的时候才会调用。
     */
    - (void)prepareLayout {
        [super prepareLayout];
        NSMutableArray *layoutInfoArr = [NSMutableArray array];
        NSInteger maxNumberOfItems = 0;
        //获取布局信息
        NSInteger numberOfSections = [self.collectionView numberOfSections];
        for (NSInteger section = 0; section < numberOfSections; section++){
            NSInteger numberOfItems = [self.collectionView numberOfItemsInSection:section];
            NSMutableArray *subArr = [NSMutableArray arrayWithCapacity:numberOfItems];
            for (NSInteger item = 0; item < numberOfItems; item++){
                NSIndexPath *indexPath = [NSIndexPath indexPathForItem:item inSection:section];
                UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForItemAtIndexPath:indexPath];
                [subArr addObject:attributes];
            }
            if(maxNumberOfItems < numberOfItems){
                maxNumberOfItems = numberOfItems;
            }
            //添加到二维数组
            [layoutInfoArr addObject:[subArr copy]];
        }
        //存储布局信息
        self.layoutInfoArray = [layoutInfoArr copy];
        //保存内容尺寸
        self.contentSize = CGSizeMake(
                                      self.contentInset.left + self.contentInset.right + maxNumberOfItems * (self.itemSize.width + self.cellSpacing) + self.cellSpacing,
                                      self.contentInset.top + self.contentInset.bottom + numberOfSections * (self.itemSize.height + self.lineSpacing) + self.lineSpacing
                                      );
    }
    
    - (CGSize)collectionViewContentSize {
        return self.contentSize;
    }
    
    - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect{
        NSMutableArray *layoutAttributesArr = [NSMutableArray array];
        [self.layoutInfoArray enumerateObjectsUsingBlock:^(NSArray *array, NSUInteger i, BOOL * _Nonnull stop) {
            [array enumerateObjectsUsingBlock:^(UICollectionViewLayoutAttributes *obj, NSUInteger idx, BOOL * _Nonnull stop) {
                if(CGRectIntersectsRect(obj.frame, rect)) {
                    [layoutAttributesArr addObject:obj];
                }
            }];
        }];
        return layoutAttributesArr;
    }
    
    - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath{
        UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
        //每一组cell为一行
        attributes.frame = CGRectMake(
                                      self.contentInset.left + (self.itemSize.width + self.cellSpacing) * indexPath.row + self.cellSpacing,
                                      self.contentInset.top + (self.itemSize.height + self.lineSpacing) * indexPath.section + self.lineSpacing,
                                      self.itemSize.width,
                                      self.itemSize.height
                                      );
        return attributes;
    }
    
    - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
        return YES;
    }
    
    @end
    
    
    
    
    //
    //  PGGridLayout.h
    //  TestCollectionView
    //
    //  Created by Yang Li on 2018/12/5.
    //  Copyright © 2018 Qiekj. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface PGGridLayout : UICollectionViewLayout
    
    //每个cell 大小
    @property(nonatomic, assign)CGSize itemSize;
    //每个cell 间的距离
    @property(nonatomic, assign)CGFloat cellSpacing;
    //一行间距
    @property(nonatomic, assign)CGFloat lineSpacing;
    //内边距
    @property(nonatomic, assign)UIEdgeInsets contentInset;
    
    @end
    
    NS_ASSUME_NONNULL_END
    
    

    相关文章

      网友评论

          本文标题:UICollectionViewLayout 自定义

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