自定义瀑布流

有时候想给不同的section设置不同的列,用这个就可以了

#import 
@protocol CCCollectionViewLayoutDelegate;
NS_ASSUME_NONNULL_BEGIN

@interface CCCollectionViewLayout : UICollectionViewLayout
@property (nonatomic, assign) CGFloat minimumLineSpacing;
@property (nonatomic, assign) CGFloat minimumInteritemSpacing;
@property (nonatomic, weak) id delegate;
@end

@protocol CCCollectionViewLayoutDelegate 
@required
-(NSInteger)ccCollectionView:(UICollectionView *)collectionView layout:(CCCollectionViewLayout *)layout numberOfColumnInSection:(NSInteger)section;
-(NSInteger)ccCollectionView:(UICollectionView *)collectionView layout:(CCCollectionViewLayout *)layout width:(CGFloat)width heightForItemAtIndexPath:(NSIndexPath *)indexPath;

@optional

- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(CCCollectionViewLayout *)layout minimumLineSpacingForSectionAtIndex:(NSInteger)section;

- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(CCCollectionViewLayout *)layout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section;

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(CCCollectionViewLayout *)layout insetForSectionAtIndex:(NSInteger)section;

- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(CCCollectionViewLayout *)layout referenceHeightForHeaderInSection:(NSInteger)section;

- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(CCCollectionViewLayout *)layout referenceHeightForFooterInSection:(NSInteger)section;
@end

NS_ASSUME_NONNULL_END

m文件

#import "CCCollectionViewLayout.h"

@interface CCCollectionViewLayout ()
@property (nonatomic, strong) NSMutableArray *> *itemLayoutAttributes;
@property (nonatomic, assign) CGFloat contentHeight;
@end

@implementation CCCollectionViewLayout

-(void)prepareLayout{
    [super prepareLayout];
    if (self.collectionView.isDecelerating || self.collectionView.isDragging) {
        return;
    }
    _contentHeight=0.0;
    self.itemLayoutAttributes=[NSMutableArray new];
    UICollectionView *collectionView = self.collectionView;
    NSInteger const numberOfSections = collectionView.numberOfSections;
    UIEdgeInsets const contentInset = collectionView.contentInset;
    CGFloat const contentWidth = collectionView.bounds.size.width - contentInset.left - contentInset.right;
    for (NSInteger section=0; section offsetOfColumns[i]) {
                    currentColumn = i;
                }
            }
            NSIndexPath *indexPath = [NSIndexPath indexPathForItem:item inSection:section];
            CGFloat itemHeight=[self.delegate ccCollectionView:collectionView layout:self width:itemWidth heightForItemAtIndexPath:indexPath];
            CGFloat x = contentInsetOfSection.left + itemWidth*currentColumn + minimumInteritemSpacing*currentColumn;
            CGFloat y = offsetOfColumns[currentColumn] + (item>=columnOfSection ? minimumLineSpacing : 0.0);
            
            UICollectionViewLayoutAttributes *layoutAttbiture = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
            layoutAttbiture.frame = CGRectMake(x, y+self.contentHeight, itemWidth, itemHeight);
            [layoutAttributeOfSection addObject:layoutAttbiture];
            
            // Update y offset in current column
            offsetOfColumns[currentColumn] = (y + itemHeight);
        }
        [self.itemLayoutAttributes addObject:layoutAttributeOfSection];
        // Get current section height from offset record.
        CGFloat maxOffsetValue = offsetOfColumns[0];
        for (int i=1; i maxOffsetValue) {
                maxOffsetValue = offsetOfColumns[i];
            }
        }
        maxOffsetValue += contentInsetOfSection.bottom;
//        [self.heightOfSections addObject:@(maxOffsetValue)];
        self.contentHeight += maxOffsetValue;
    }
}

- (CGSize)collectionViewContentSize {
    UIEdgeInsets contentInset = self.collectionView.contentInset;
    CGFloat width = CGRectGetWidth(self.collectionView.bounds) - contentInset.left - contentInset.right;
    CGFloat height = MAX(CGRectGetHeight(self.collectionView.bounds), _contentHeight);
    return CGSizeMake(width, height);
}

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
    NSMutableArray *result = [NSMutableArray array];
    [self.itemLayoutAttributes enumerateObjectsUsingBlock:^(NSMutableArray *layoutAttributeOfSection, NSUInteger idx, BOOL *stop) {
        [layoutAttributeOfSection enumerateObjectsUsingBlock:^(UICollectionViewLayoutAttributes *attribute, NSUInteger idx, BOOL *stop) {
            if (CGRectIntersectsRect(rect, attribute.frame)) {
                [result addObject:attribute];
            }
        }];
    }];
    
    return result;
}

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
    return self.itemLayoutAttributes[indexPath.section][indexPath.item];
}

- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
    return YES;
}

#pragma mark Private

- (UIEdgeInsets)contentInsetForSection:(NSInteger)section {
    UIEdgeInsets edgeInsets = UIEdgeInsetsZero;
    if ([self.delegate respondsToSelector:@selector(collectionView:layout:insetForSectionAtIndex:)]) {
        edgeInsets = [self.delegate collectionView:self.collectionView layout:self insetForSectionAtIndex:section];
    }
    return edgeInsets;
}

- (CGFloat)minimumLineSpacingForSection:(NSInteger)section {
    CGFloat minimumLineSpacing = self.minimumLineSpacing;
    if ([self.delegate respondsToSelector:@selector(collectionView:layout:minimumLineSpacingForSectionAtIndex:)]) {
        minimumLineSpacing = [self.delegate collectionView:self.collectionView layout:self minimumLineSpacingForSectionAtIndex:section];
    }
    return minimumLineSpacing;
}

- (CGFloat)minimumInteritemSpacingForSection:(NSInteger)section {
    CGFloat minimumInteritemSpacing = self.minimumInteritemSpacing;
    if ([self.delegate respondsToSelector:@selector(collectionView:layout:minimumInteritemSpacingForSectionAtIndex:)]) {
        minimumInteritemSpacing = [self.delegate collectionView:self.collectionView layout:self minimumInteritemSpacingForSectionAtIndex:section];
    }
    return minimumInteritemSpacing;
}

@end

你可能感兴趣的:(自定义瀑布流)