UICollectionView的自定義流水布局

屏幕快照 2017-01-19 下午3.02.00.png

LineLayout.h文件

#import <UIKit/UIKit.h>

@interface LineLayout : UICollectionViewFlowLayout

@end

LineLayout.m文件

#import "LineLayout.h"

@implementation LineLayout

- (instancetype)init
{
    if (self = [super init]) {
    }
    return self;
}

/**
 * 當(dāng)collectionView的顯示范圍發(fā)生改變的時(shí)候,是否需要重新刷新布局
 * 一旦重新刷新布局,就會(huì)重新調(diào)用下面的方法:
 1.prepareLayout
 2.layoutAttributesForElementsInRect:方法
 */
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
    return YES;
}

/**
 * 用來做布局的初始化操作(不建議在init方法中進(jìn)行布局的初始化操作)
 */
- (void)prepareLayout
{
    [super prepareLayout];
    
    // 水平滾動(dòng)
    self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
    
    // 設(shè)置左右內(nèi)邊距
    CGFloat inset = (self.collectionView.frame.size.width - self.itemSize.width) * 0.5;
    self.sectionInset = UIEdgeInsetsMake(0, inset, 0, inset);
}

/**
 UICollectionViewLayoutAttributes *attrs;
 1.一個(gè)cell對(duì)應(yīng)一個(gè)UICollectionViewLayoutAttributes對(duì)象
 2.UICollectionViewLayoutAttributes對(duì)象決定了cell的frame
 */
/**
 * 這個(gè)方法的返回值是一個(gè)數(shù)組(數(shù)組里面存放著rect范圍內(nèi)所有元素的布局屬性)
 * 這個(gè)方法的返回值決定了rect范圍內(nèi)所有元素的排布(frame)
 * cell的放大和縮小
 */
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
    // 獲得super已經(jīng)計(jì)算好的布局屬性
    NSArray *array = [super layoutAttributesForElementsInRect:rect];
    
    // 計(jì)算collectionView最中心點(diǎn)的x值
    CGFloat centerX = self.collectionView.contentOffset.x + self.collectionView.frame.size.width * 0.5;
    
    // 在原有布局屬性的基礎(chǔ)上,進(jìn)行微調(diào)
    for (UICollectionViewLayoutAttributes *attrs in array) {
        // cell的中心點(diǎn)x 和 collectionView最中心點(diǎn)的x值 的間距
        CGFloat delta = ABS(attrs.center.x - centerX);
        
        // 根據(jù)間距值 計(jì)算 cell的縮放比例
        CGFloat scale = 1 - delta / self.collectionView.frame.size.width;
        
        // 設(shè)置縮放比例
        attrs.transform = CGAffineTransformMakeScale(scale, scale);
    }
    
    return array;
}

/**
 * 這個(gè)方法的返回值,就決定了collectionView停止?jié)L動(dòng)時(shí)的偏移量
 * 停止?jié)L動(dòng)時(shí):cell居中
 */
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{
    // 計(jì)算出最終顯示的矩形框
    CGRect rect;
    rect.origin.y = 0;
    rect.origin.x = proposedContentOffset.x;
    rect.size = self.collectionView.frame.size;
    
    // 獲得super已經(jīng)計(jì)算好的布局屬性
    NSArray *array = [super layoutAttributesForElementsInRect:rect];
    
    // 計(jì)算collectionView最中心點(diǎn)的x值
    CGFloat centerX = proposedContentOffset.x + self.collectionView.frame.size.width * 0.5;
    
    // 存放最小的間距值
    CGFloat minDelta = MAXFLOAT;
    for (UICollectionViewLayoutAttributes *attrs in array) {
        if (ABS(minDelta) > ABS(attrs.center.x - centerX)) {
            minDelta = attrs.center.x - centerX;
        }
    }
    
    // 修改原有的偏移量
    proposedContentOffset.x += minDelta;
    return proposedContentOffset;
}
@end

/**
 1.cell的放大和縮小
 2.停止?jié)L動(dòng)時(shí):cell的居中
 */

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容