UICollectionView Custom layout UICollectionViewDelegateFlowLayout-横向滚动 中间吸附 布局

来源:互联网 发布:表格中数据单位转换 编辑:程序博客网 时间:2024/06/08 03:19

@protocol HCenterCVDelegateFlowLayout <UICollectionViewDelegateFlowLayout>

@optional

-(void)collectionView:(UICollectionView *)collectionView

               layout:(UICollectionViewLayout*)collectionViewLayout

     layoutAttributes:(HCenterCVLayoutAttributes *) attributes

          atIndexPath:(NSIndexPath *)indexPath;

-(void) collectionView:(UICollectionView *)collectionView willAdsorptToIndexPath:(NSIndexPath *)indexPath;


@end

@interface HCenterCVFlowLayout :BCollectionViewFlowLayout

@end

#import "HCenterCVFlowLayout.h"


#import "HCenterCVLayoutAttributes.h"


@implementation HCenterCVFlowLayout


-(instancetype) initWithCoder:(NSCoder *)aDecoder{

    self = [superinitWithCoder:aDecoder];

    returnself;

}


- (void)prepareLayout{

    // The collection view calls -prepareLayout once at its first layout as the first message to the layout instance.

    // The collection view calls -prepareLayout again after layout is invalidated and before requerying the layout information.

    // Subclasses should always call super if they override.

    [superprepareLayout];

}


- (CGSize)collectionViewContentSize{

    NSInteger cellCount = [self.collectionViewnumberOfItemsInSection:0];

    CGFloat width =CGRectGetWidth(self.collectionView.bounds) +  (cellCount -1) * self.itemSize.width +self.sectionInset.left +self.sectionInset.right;

    if (cellCount >0) {

        width += (cellCount - 1) *self.minimumLineSpacing;

    }

    CGFloat height =self.itemSize.height +self.sectionInset.top +self.sectionInset.bottom;

    

    returnCGSizeMake(width, height);

}


//#pragma attribute


+(Class)layoutAttributesClass {

    return [HCenterCVLayoutAttributesclass];

}


-(void)applyLayoutAttributes:(HCenterCVLayoutAttributes *)attributes {

    // private

    if (attributes.representedElementKind ==nil)

    {

        // Check for representedElementKind being nil,

        // indicating this is a cell and not a header or decoration view

        

        if ([self.collectionView.delegaterespondsToSelector: @selector(collectionView:layout:layoutAttributes:atIndexPath:)]){

            id<HCenterCVDelegateFlowLayout> flowlayout = (id<HCenterCVDelegateFlowLayout>)self.collectionView.delegate;

            [flowlayout collectionView:self.collectionView

                                layout:self

                      layoutAttributes:attributes

                           atIndexPath:attributes.indexPath];

        }

        CGFloat pX =CGRectGetWidth(self.collectionView.bounds) /2;

        pX += attributes.indexPath.row  * (self.minimumLineSpacing + self.itemSize.width);

        attributes.center =CGPointMake( pX, attributes.center.y);

        CGPoint contentOffset =self.collectionView.contentOffset;

        CGFloat currentCenter = contentOffset.x +CGRectGetWidth(self.collectionView.bounds) /2;

        CGFloat dlt =fabs(currentCenter - pX);

        if (dlt <=self.itemSize.width) {

            attributes.transform3D =CATransform3DIdentity;

            attributes.transform3D =CATransform3DMakeScale( 0.9 +0.1 * (1 -dlt /self.itemSize.width),0.90.1 * (1 -dlt /self.itemSize.width) ,1);

        }else{

            attributes.transform3D =CATransform3DIdentity;

            attributes.transform3D =CATransform3DMakeScale( 0.9,0.9, 1);

        }

        

    }

}


- (nullableNSArray<__kindofUICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect{

    NSArray *attributesArray = [superlayoutAttributesForElementsInRect:rect];

    for (HCenterCVLayoutAttributes *attributesin attributesArray) {

        [selfapplyLayoutAttributes:attributes];

    }

    return attributesArray;

}

- (nullableUICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath{

    HCenterCVLayoutAttributes *attributes = (HCenterCVLayoutAttributes *)[superlayoutAttributesForItemAtIndexPath:indexPath];

    [selfapplyLayoutAttributes:attributes];

    return attributes;

}


////- (nullable UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath;

////- (nullable UICollectionViewLayoutAttributes *)layoutAttributesForDecorationViewOfKind:(NSString*)elementKind atIndexPath:(NSIndexPath *)indexPath;



#pragma  context invalidate


+ (Class)invalidationContextClass NS_AVAILABLE_IOS(7_0){

    // override this method to provide a custom class to be used for invalidation contexts

    return [superinvalidationContextClass];

}


- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds{

    // return YES to cause the collection view to requery the layout for geometry information

    returnYES;

}

- (UICollectionViewLayoutInvalidationContext *)invalidationContextForBoundsChange:(CGRect)newBoundsNS_AVAILABLE_IOS(7_0){

    return [superinvalidationContextForBoundsChange:newBounds];

}


- (BOOL)shouldInvalidateLayoutForPreferredLayoutAttributes:(UICollectionViewLayoutAttributes *)preferredAttributes

                                    withOriginalAttributes:(UICollectionViewLayoutAttributes *)originalAttributesNS_AVAILABLE_IOS(8_0){

    returnNO;

}

- (UICollectionViewLayoutInvalidationContext *)invalidationContextForPreferredLayoutAttributes:(UICollectionViewLayoutAttributes *)preferredAttributes

                                                                        withOriginalAttributes:(UICollectionViewLayoutAttributes *)originalAttributesNS_AVAILABLE_IOS(8_0){

    return [superinvalidationContextForPreferredLayoutAttributes:preferredAttributeswithOriginalAttributes:originalAttributes];

}



#pragma postition and content size


- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity{

    // return a point at which to rest after scrolling - for layouts that want snap-to-point scrolling behavior


    CGFloat proposedCenterX = proposedContentOffset.x +CGRectGetWidth(self.collectionView.bounds) /2;

    CGFloat nearIndex =  (proposedContentOffset.x -self.itemSize.width /2) / (self.minimumLineSpacing +self.itemSize.width);

    NSInteger pos =ceil(nearIndex);

    proposedCenterX = CGRectGetWidth(self.collectionView.bounds) / 2;

    proposedCenterX += pos * (self.minimumLineSpacing +self.itemSize.width);

    NSIndexPath * indexPath = [NSIndexPathindexPathForRow:pos inSection:0];

    

    if ([self.collectionView.delegaterespondsToSelector:@selector(collectionView:willAdsorptToIndexPath:)]) {

        id<HCenterCVDelegateFlowLayout> centerDelegate = (id<HCenterCVDelegateFlowLayout>)self.collectionView.delegate;

        [centerDelegate collectionView:self.collectionViewwillAdsorptToIndexPath:indexPath];

    }

    returnCGPointMake(proposedCenterX - CGRectGetWidth(self.collectionView.bounds) /2, proposedContentOffset.y);

}


- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffsetNS_AVAILABLE_IOS(7_0){

    // a layout can return the content offset to be applied during transition or update animations

    return proposedContentOffset;

}


@end


0 0
原创粉丝点击