UICollectionViewController的使用详解

UICollectionViewController的使用详解

    // 设置 collectionView 的数据源代理

    _collectionView.dataSource = self;

    

    // 修改collectionView的背景色

    _collectionView.backgroundColor = [UIColor whiteColor];

    

    

    // 隐藏滚动条

    _collectionView.showsHorizontalScrollIndicator = NO;

    

    // 设置分页效果

    _collectionView.pagingEnabled = YES;

    

    // 设置弹簧效果

    _collectionView.bouncesNO;



    /**

     collectionView  必须有一个 layout

     storyboard 上拖拽的时候, 已经自动添加一个 流水布局

     UICollectionView must be initialized with a non-nil layout parameter

     */

    

    /**

     实例化一个layout对象

     collectionView 如果要使用layout 必须在实例化的时候就进行设置

     

     

     UICollectionViewLayout      是流水布局的父类, 最纯净的layout

     UICollectionViewFlowLayout  是在父类上做了一些相应的扩展

     */

    

    UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];

    

    // 修改cell 的大小 , 默认是 50 , 50

    flowLayout.itemSize = CGSizeMake(100, 100);

    // 修改cell距离view的边距

    _flowLayout.sectionInset = UIEdgeInsetsMake(40, 10, 0, 10);

    

    // 修改滚动方向

//    _flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;


    // 下面两个属性是和 滚动方向有关的

    

    // 最小列之间的间距

    _flowLayout.minimumInteritemSpacing = 50;

    

    // 设置最小行间距

//    flowLayout.minimumLineSpacing = 100;

    



    // 实例化一个collectionView

    

    UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds  collectionViewLayout:flowLayout];

    

    collectionView.dataSource = self;

    

    // 添加到控制器的view

    [self.view addSubview:collectionView];

    

    // 设置背景色

    collectionView.backgroundColor = [UIColor whiteColor];

    

    // 注册一个cell

    [collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:identifier];

    /**

     取出 collectionView flowlayout

     

     self.collectionViewLayout  只读的

     

     self.collectionView.collectionViewLayout  做一步强转 

     */

    

    UICollectionViewFlowLayout *folowLayout = (UICollectionViewFlowLayout *)self.collectionView.collectionViewLayout;

    

    

    folowLayout.itemSize = CGSizeMake(100, 100);

    

    // Pin 钉住, 类似tableView的悬浮效果

    folowLayout.sectionFootersPinToVisibleBounds = YES;

    folowLayout.sectionHeadersPinToVisibleBounds = YES;

    

    // 在垂直滚动的时候, 设置宽度无效

    // 水平滚动的时候, 设置高度无效

//    folowLayout.headerReferenceSize = CGSizeMake(10, 50);//设置头部宽度

//    folowLayout.footerReferenceSize = CGSizeMake(20, 70);




// 取消选中

- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath {

    NSLog(@"取消选中 - %ld", indexPath.item);

}


// 被选中

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {

    // item 就相当于row

    NSLog(@"%ld", indexPath.item);

}


#pragma mark - 这个方法会反回所有cell的属性设置

// 反回的数组中, UICollectionViewLayoutAttributes 对象, 包含了cell的属性

- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {

    // 1. 取出所有的item UICollectionViewLayoutAttributes


    NSArray *superAttributes = [super layoutAttributesForElementsInRect:rect];

    

    // 2. 计算出屏幕的中心点, 中心点必须加上 collectionView的偏移量.x

    CGFloat screenCenter = self.collectionView.contentOffset.x + self.collectionView.frame.size.width/2;

    

    // 通过循环遍历 可以对 item的属性进行修改

    for (UICollectionViewLayoutAttributes *itemAttributes in superAttributes) {

        

        // 3. 计算差值 ABS() 取绝对值

        CGFloat deltaMargin = ABS(screenCenter - itemAttributes.center.x);

        

        // 4. 计算一个放大比率 , cell 和中心点的距离  方大的比率成反比

        CGFloat scaleDelta = 1.1 - deltaMargin / (self.collectionView.frame.size.width/2 + itemAttributes.size.width);

        

        

        itemAttributes.transform = CGAffineTransformMakeScale(scaleDelta, scaleDelta);

    }

    

    return superAttributes;

}


#pragma mark -

#pragma mark -  当手指离开collectionView的时候会调用

/**

 targetContentOffset     --- > 最终停留的位置 (进行干预后停留的位置)

 

 ProposedContentOffset   --->  本应该停留的位置

 

 velocity  力度, 速度

 */

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

    

    // 1. 取出屏幕的中心点

    CGFloat screenCenter = proposedContentOffset.x + self.collectionView.frame.size.width/2;

    

    // 2. 取出可见范围内的cell

    CGRect visibleRect = CGRectZero;

    

    visibleRect.size = self.collectionView.frame.size;

    visibleRect.origin = proposedContentOffset;

    

    //  得到的是 可见范围内的cell属性集合  调用super 的方法, 是避免重新计算比率

    NSArray *visibleArray = [super layoutAttributesForElementsInRect:visibleRect];

//定义最小的间距

    CGFloat minMargin=MAXFLOAT;

    

    for(UICollectionViewLayoutAttributes *attributes in visibleArray){

    //取出cell的中心和屏幕中心的间距

        CGFloat delMargin=attributes.center.x-screenCenter;

        

        if (ABS(minMargin)>ABS(delMargin)) {

            minMargin=delMargin;

            

        }

    }

        return CGPointMake(proposedContentOffset.x+minMargin, proposedContentOffset.y);

    

    

}





#pragma mark -

#pragma mark -  当屏幕的可见范围发生变化的时候, 要重新刷新布局

- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {

    

    return YES;

}



#pragma mark -

#pragma mark - 当布局刷新的时候, 就会自动调用这个方法

// 建议在这个方法里进行初始化的设置

- (void)prepareLayout {

    [super prepareLayout];

    

    // 修改滚动方向

    self.scrollDirection = UICollectionViewScrollDirectionHorizontal;

    

    // 取出collectionViewsize

    CGSize collectionViewSize = self.collectionView.frame.size;

    

    // 设置item的宽高

    CGFloat itemWidth = collectionViewSize.height * 0.6;

    

    // 设置item的高度

    CGFloat itemHeight = collectionViewSize.height * 0.8;

    

    // 修改itemsize

    self.itemSize = CGSizeMake(itemWidth, itemHeight);

    

    // 设置头部和尾部的初始间距

    CGFloat margin = collectionViewSize.width/2 - itemWidth/2;

    

    self.sectionInset = UIEdgeInsetsMake(0, margin, 0, margin);

    

}



你可能感兴趣的:(UICollectionViewController的使用详解)