iOS代码片段

71 阅读1分钟

//

//  OCFTUICollectionViewLeftAlignedFlowLayout.m

//  ZNSLSDK

//

//  Created by on 2022/4/12.

//  Copyright © 2022 yull. All rights reserved.

//

#import "OCFTUICollectionViewLeftAlignedFlowLayout.h"

#define OCFTItemWidth 115.f

#define kDecorationReuseIndentifier @"kUICollectionSectionColorIndentifier"

@interface UICollectionViewLayoutAttributes (OCFTLeftAligned)

  • (void)ocftLeftAlignFrameWithSectionInset:(UIEdgeInsets)sectionInset;

@end

@implementation UICollectionViewLayoutAttributes (OCFTLeftAligned)

  • (void)ocftLeftAlignFrameWithSectionInset:(UIEdgeInsets)sectionInset

{

    CGRect frame = self.frame;

    frame.origin.x = sectionInset.left;

    self.frame = frame;

}

@end

@interface UICollectionSectionColorLayoutAttributes : UICollectionViewLayoutAttributes

@property (nonatomic, assign) NSInteger tagg;

@property(nonatomic, strong) UIColor *sectionBgColor;

@property (nonatomic, assign) CGFloat sectionCornerRadius;

@property(nonatomic, strong) UIColor *shadowColor;

@property (nonatomic, assign) CGFloat shadowRadius;

@end

@implementation UICollectionSectionColorLayoutAttributes

@end

@implementation UICollectionSectionColorReusableView

  • (void)applyLayoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes {

    [super applyLayoutAttributes:layoutAttributes];

    if ([layoutAttributes isKindOfClass:[UICollectionSectionColorLayoutAttributes class]]) {

        self.tag = [(UICollectionSectionColorLayoutAttributes *)layoutAttributes tagg];

        self.backgroundColor = [(UICollectionSectionColorLayoutAttributes *)layoutAttributes sectionBgColor];

        self.layer.cornerRadius = [(UICollectionSectionColorLayoutAttributes *)layoutAttributes sectionCornerRadius];

        self.layer.shadowColor = [(UICollectionSectionColorLayoutAttributes *)layoutAttributes shadowColor].CGColor;

        self.layer.shadowOffset = CGSizeZero;

        self.layer.shadowRadius = [(UICollectionSectionColorLayoutAttributes *)layoutAttributes shadowRadius];

        self.layer.shadowOpacity = 10.f;

    }

}

@end

@interface OCFTUICollectionViewLeftAlignedFlowLayout () {

    NSMutableArray *_decorationViewAttrs;

}

@end

@implementation OCFTUICollectionViewLeftAlignedFlowLayout

#pragma mark - UICollectionViewLayout

  • (void)prepareLayout {

    [super prepareLayout];

    NSInteger numberOfSections = self.collectionView.numberOfSections;

    if (numberOfSections == 0) {

        return;

    }

    [self registerClass:[UICollectionSectionColorReusableView class] forDecorationViewOfKind:kDecorationReuseIndentifier];

    if (!_decorationViewAttrs) {

        _decorationViewAttrs = [NSMutableArray array];

    }else{

        [_decorationViewAttrs removeAllObjects];

    }

    for (int i = 0; i < numberOfSections; i ++) {

        NSInteger  numberOfItems = [self.collectionView numberOfItemsInSection:i];

        if (numberOfItems == 0 || ![self.collectionView.delegate conformsToProtocol:@protocol(OCFTUICollectionViewDelegateLeftAlignedFlowLayout)]) {

            continue;

        }

        UICollectionViewLayoutAttributes *firstAttr = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:i]];

        UICollectionViewLayoutAttributes *lastAttr = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForRow:numberOfItems - 1 inSection:i]];

        CGRect sectionFrame = CGRectUnion(firstAttr.frame, lastAttr.frame);

        sectionFrame.origin.x -= self.sectionInset.left;

        sectionFrame.origin.y -= self.sectionInset.top;

        if (self.scrollDirection == UICollectionViewScrollDirectionHorizontal) {

            sectionFrame.size.width += self.sectionInset.left + self.sectionInset.right;

            sectionFrame.size.height = self.collectionView.frame.size.height;

        }else{

            CGFloat itemWidth = ([UIScreen mainScreen].bounds.size.width - 32 - 7)/3.f;

            if (itemWidth >= OCFTItemWidth) {

                itemWidth = OCFTItemWidth;

            }

            sectionFrame.size.width = itemWidth * numberOfItems;

            sectionFrame.size.height += self.sectionInset.top + self.sectionInset.bottom;

        }

        

        UICollectionSectionColorLayoutAttributes *decorationAttributes = [UICollectionSectionColorLayoutAttributes layoutAttributesForDecorationViewOfKind:kDecorationReuseIndentifier withIndexPath:[NSIndexPath indexPathForRow:0 inSection:i]];

        decorationAttributes.frame = sectionFrame;

        decorationAttributes.zIndex= -1;

        decorationAttributes.tagg = 10000 + i;

        UIColor *sectionBgColor = nil;

        if ([self.collectionView.delegate respondsToSelector:@selector(collectionView:layout:backgroundColorForSection:)]) {

            id delegate = (id)self.collectionView.delegate;

            sectionBgColor = [delegate collectionView:self.collectionView layout:self backgroundColorForSection:i];

        }

        decorationAttributes.sectionBgColor = sectionBgColor;

        

        CGFloat sectionCornerRadius = 0.f;

        if ([self.collectionView.delegate respondsToSelector:@selector(collectionView:layout:cornerRadiusForSection:)]) {

            id delegate = (id)self.collectionView.delegate;

            sectionCornerRadius = [delegate collectionView:self.collectionView layout:self cornerRadiusForSection:i];

        }

        decorationAttributes.sectionCornerRadius = sectionCornerRadius;

        

        UIColor *shadowColor = nil;

        if ([self.collectionView.delegate respondsToSelector:@selector(collectionView:layout:shadowColorForSection:)]) {

            id delegate = (id)self.collectionView.delegate;

            shadowColor = [delegate collectionView:self.collectionView layout:self shadowColorForSection:i];

        }

        decorationAttributes.shadowColor = shadowColor;

        

        CGFloat shadowRadius = 0.f;

        if ([self.collectionView.delegate respondsToSelector:@selector(collectionView:layout:shadowRadiusForSection:)]) {

            id delegate = (id)self.collectionView.delegate;

            shadowRadius = [delegate collectionView:self.collectionView layout:self shadowRadiusForSection:i];

        }

        decorationAttributes.shadowRadius = shadowRadius;

        

        [_decorationViewAttrs addObject:decorationAttributes];

    }

}

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

    NSArray *originalAttributes = [super layoutAttributesForElementsInRect:rect];

    NSMutableArray *updatedAttributes = [NSMutableArray arrayWithArray:originalAttributes];

    for (UICollectionViewLayoutAttributes *attributes in originalAttributes) {

        if (!attributes.representedElementKind) {

            NSUInteger index = [updatedAttributes indexOfObject:attributes];

            updatedAttributes[index] = [self layoutAttributesForItemAtIndexPath:attributes.indexPath];

        }

    }

    for (UICollectionSectionColorLayoutAttributes *attr in _decorationViewAttrs) {

        if (CGRectIntersectsRect(rect, attr.frame)) {

            [updatedAttributes addObject:attr];

        }

    }

    return updatedAttributes;

}

  • (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {

    UICollectionViewLayoutAttributes* currentItemAttributes = [[super layoutAttributesForItemAtIndexPath:indexPath] copy];

    UIEdgeInsets sectionInset = [self evaluatedSectionInsetForItemAtIndex:indexPath.section];

    BOOL isFirstItemInSection = indexPath.item == 0;

    CGFloat layoutWidth = CGRectGetWidth(self.collectionView.frame) - sectionInset.left - sectionInset.right;

    if (isFirstItemInSection) {

        [currentItemAttributes ocftLeftAlignFrameWithSectionInset:sectionInset];

        return currentItemAttributes;

    }

    NSIndexPath* previousIndexPath = [NSIndexPath indexPathForItem:indexPath.item-1 inSection:indexPath.section];

    CGRect previousFrame = [self layoutAttributesForItemAtIndexPath:previousIndexPath].frame;

    CGFloat previousFrameRightPoint = previousFrame.origin.x + previousFrame.size.width;

    CGRect currentFrame = currentItemAttributes.frame;

    CGRect strecthedCurrentFrame = CGRectMake(sectionInset.left,

                                              currentFrame.origin.y,

                                              layoutWidth,

                                              currentFrame.size.height);

    // if the current frame, once left aligned to the left and stretched to the full collection view

    // width intersects the previous frame then they are on the same line

    BOOL isFirstItemInRow = !CGRectIntersectsRect(previousFrame, strecthedCurrentFrame);

    if (isFirstItemInRow) {

        // make sure the first item on a line is left aligned

        [currentItemAttributes ocftLeftAlignFrameWithSectionInset:sectionInset];

        return currentItemAttributes;

    }

    CGRect frame = currentItemAttributes.frame;

    frame.origin.x = previousFrameRightPoint + [self evaluatedMinimumInteritemSpacingForSectionAtIndex:indexPath.section];

    currentItemAttributes.frame = frame;

    return currentItemAttributes;

}

  • (CGFloat)evaluatedMinimumInteritemSpacingForSectionAtIndex:(NSInteger)sectionIndex

{

    if ([self.collectionView.delegate respondsToSelector:@selector(collectionView:layout:minimumInteritemSpacingForSectionAtIndex:)]) {

        id delegate = (id)self.collectionView.delegate;

        return [delegate collectionView:self.collectionView layout:self minimumInteritemSpacingForSectionAtIndex:sectionIndex];

    } else {

        return self.minimumInteritemSpacing;

    }

}

  • (UIEdgeInsets)evaluatedSectionInsetForItemAtIndex:(NSInteger)index

{

    if ([self.collectionView.delegate respondsToSelector:@selector(collectionView:layout:insetForSectionAtIndex:)]) {

        id delegate = (id)self.collectionView.delegate;

        return [delegate collectionView:self.collectionView layout:self insetForSectionAtIndex:index];

    } else {

        return self.sectionInset;

    }

}

@end