UICollectionView自定义布局以及相册浏览效果

UICollectionView自定义布局掌握的五个方法:

// 作用:计算cell位置,只要计算一次,前提:cell的位置一开始就是固定
// 什么时候调用:第一次布局调用,每次刷新collectionView也会调用// 注意:必须要调用[super prepareLayout]
- (void)prepareLayout{
    [super prepareLayout];
}

// UICollectionViewLayoutAttributes:cell的布局对象
// 每一个cell对应UICollectionViewLayoutAttributes
// UICollectionViewLayoutAttributes用来描述cell的布局
// UICollectionViewLayoutAttributes就是cell
// 作用:指定一个区域,就会返回这个区域内的所有cell布局
// 这个可以一次性返回所有cell布局,也可以分批方法
// 操作cell布局
- (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
{
    // 获取显示范围   
    CGRect visableRect = self.collectionView.bounds;    
    NSArray *attrs = [super layoutAttributesForElementsInRect:visableRect];     
    for (UICollectionViewLayoutAttributes *attr in attrs) {

       }    
    NSLog(@"%@",attrs);
    return attrs;
}

// Invalidate:刷新
// 在拖动内容是否允许属性布局
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds{
    return YES;
}

// 什么时候调用:在拖动的时候,手指抬起调用
// 作用:返回最终偏移量,最终collectionView停到哪个位置
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{
    // 第一个参数:就是最终偏移量, 手指快速拖动视图减速直到停止的偏移量 == proposedContentOffset参数
    CGPoint targetOffset = [super targetContentOffsetForProposedContentOffset:proposedContentOffset withScrollingVelocity:velocity]; 
    // self.collectionView.contentOffset 获取手指抬起时,collectionView的偏移量
   NSLog(@"%@ %@", NSStringFromCGPoint(self.collectionView.contentOffset),NSStringFromCGPoint(proposedContentOffset));
       return targetOffset;
}

// 作用:计算collectionView滚动范围
- (CGSize)collectionViewContentSize{
    return [super collectionViewContentSize];
}
如下效果图所示,原理其实还是collectionView自定义其layout
自定义FlowLayout继承UICollectionViewFlowLayout,其.m文件实现如下:
@implementation FlowLayout

// 作用:计算cell位置,只要计算一次,前提:cell的位置一开始就是固定
// 什么时候调用:第一次布局调用,每次刷新collectionView也会调用
// 注意:必须要调用[super prepareLayout]
//- (void)prepareLayout
//{
//    [super prepareLayout];
//
//}

// UICollectionViewLayoutAttributes:cell的布局对象
// 每一个cell对应UICollectionViewLayoutAttributes
// UICollectionViewLayoutAttributes用来描述cell的布局
// UICollectionViewLayoutAttributes就是cell

// 作用:指定一个区域,就会返回这个区域内的所有cell布局
// 这个可以一次性返回所有cell布局,也可以分批方法
// 操作cell布局
- (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
{
    // 哪些cell需要进行缩放,显示cell才需要做缩放,获取显示出来cell布局,获取显示范围
    // 问题:什么时候缩放,什么时候放大
    // 离中心点越近,cell越大,离中心点越远,cell越小
    // 缩放跟中心点成反比
    // 计算中心点
    
    // 获取显示范围
    CGRect visableRect = self.collectionView.bounds;
    
    NSArray *attrs = [super layoutAttributesForElementsInRect:visableRect];
     ;
    
    for (UICollectionViewLayoutAttributes *attr in attrs) {
        // 获取距离中心点的位置
        CGFloat delta =fabs(attr.center.x - (self.collectionView.contentOffset.x + XMGScreenW * 0.5));
        // 每个cell进行缩放 1 ~ 0.5
        CGFloat scale = 1 - delta / (XMGScreenW * 0.5) * 0.25;
        
        attr.transform = CGAffineTransformMakeScale(scale, scale);
        
    }
    
    return attrs;
}
// 作用:
// Invalidate:刷新
// 在拖动内容是否允许属性布局
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
    return YES;
}

// 什么时候调用:在拖动的时候,手指抬起调用
// 作用:返回最终偏移量,最终collectionView停到哪个位置
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{
    // 定位:判断下谁离中心点近,就显示在中心位置
    // 判断下最终显示那块区域
    // 获取最终显示区域
    CGRect targetRect = CGRectMake(proposedContentOffset.x, 0, XMGScreenW, MAXFLOAT);
    
    // 获取最终显示区域下所有cell,去判断下哪个离中心点近
    NSArray *attrs = [super layoutAttributesForElementsInRect:targetRect];
    
    // 判断下哪个离中心点
    CGFloat minDelta = MAXFLOAT;
    for (UICollectionViewLayoutAttributes *attr in attrs) {
        // 获取中心点距离
        CGFloat delta =attr.center.x - (self.collectionView.contentOffset.x + XMGScreenW * 0.5);
        if (fabs(delta) 
调用(特地介绍以下这种写法:其实这是C语言的逗号表达式,忘记是什么鬼请问度娘)
    FlowLayout *layout = ({
        layout = [[FlowLayout alloc] init];
        // 设置cell尺寸
        layout.itemSize = CGSizeMake(160, 160);
        // 设置最小行间距为0
        layout.minimumLineSpacing = 30;
        // 设置滚动方向
        layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
        // 设置额外滚动区域
        CGFloat inset = (self.view.bounds.size.width - 160) * 0.5;
        layout.sectionInset = UIEdgeInsetsMake(0, inset, 0, inset);
        layout;
    });

你可能感兴趣的:(UICollectionView自定义布局以及相册浏览效果)