【iOS系列】- iOS吸附效果的实现 之 UICollectionView的使用全解

【iOS系列】- iOS吸附效果的实现 之 UICollectionView的使用全解

UICollectionView可以做很多的布局,在iOS开发中较为重要,所以这里就以实例来讲解UICollectionView的使用进阶。

注: 用StoryBoard拖出来的UICollectionView的布局就是流水布局,无法修改,所以如果要实现一些自定义的效果需要通过代码创建UICollectionView

项目示例如下:效果为吸附的效果,App Store中也有类似的效果,就是单元格出来小于一半:则就让其回退;如果大于一半:则就让其直接移出界面显示区域:

uicollectionview_1.gif

Demo下载地址:iOS_Demo

一些概念

UICollectionView中有个重要的内容UICollectionViewLayout,UICollectionView的显示是由其布局文件决定的。

UICollectionViewFlowLayout:系统提供的流水布局,如果要自定义流水布局的效果可以自定义这个类。

布局决定每一个cell的尺寸,位置,间距等等。

每一个cell/item都有自己UICollectionViewLayoutAttributes

每一个indexPath也都有自己UICollectionViewLayoutAttributes


开始

所以这次做的吸附效果也完全是自定义了UICollectionViewFlowLayout

下面对这个类的主要方法进行大体介绍:

  1. prepareLayout:一些初始化的工作最好这里完成,比如item的大小等等

     -(void)prepareLayout
     {
     [super prepareLayout];//需要调用super方法
    
     //初始化
     self.itemSize = CGSizeMake(90, 90);//设置item的大小
     self.scrollDirection = UICollectionViewScrollDirectionHorizontal;//设置滚动防线
     self.minimumLineSpacing = 10;//设置cell的间距
     self.sectionInset = UIEdgeInsetsMake(0, 10, 0, 10);//设置四周的间距
     }
  2. targetContentOffsetForProposedContentOffset:控制控制最后UICollectionView的最后去哪里,我们这里需要做的吸附效果的逻辑代码就需要在这里完成。参数介绍proposedContentOffset:原本UICollectionView停止滚动那一刻的位置;velocity:滚动速度

     -(CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
     {
         //TODO
     }
  3. shouldInvalidateLayoutForBoundsChange:边界发生改变时,是否需要重新布局,返回YES就需要重新布局(会自动调用layoutAttributesForElementsInRect方法,获得所有cell的布局属性)

     -(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds

    {
    return YES;
    }

  4. layoutAttributesForElementsInRect:返回所有cell的布局属性

     -(NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
     {
         return [super layoutAttributesForElementsInRect:rect];
     }

方法介绍完毕,我们在prepareLayout

-(CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{
    //1.计算scrollview最后停留的范围
    CGRect lastRect ;
    lastRect.origin = proposedContentOffset;
    lastRect.size = self.collectionView.frame.size;
    
    //2.取出这个范围内的所有属性
    NSArray *array = [self layoutAttributesForElementsInRect:lastRect];
    
    //起始的x值,也即默认情况下要停下来的x值
    CGFloat startX = proposedContentOffset.x;
    
    //3.遍历所有的属性
    CGFloat adjustOffsetX = MAXFLOAT;
    for (UICollectionViewLayoutAttributes *attrs in array) {
        CGFloat attrsX = CGRectGetMinX(attrs.frame);
        CGFloat attrsW = CGRectGetWidth(attrs.frame) ;

        if (startX - attrsX  < attrsW/2) {
            adjustOffsetX = -(startX - attrsX+ItemMaigin);
        }else{
            adjustOffsetX = attrsW - (startX - attrsX);
        }
    
        break ;//只循环数组中第一个元素即可,所以直接break了
    }
    return CGPointMake(proposedContentOffset.x + adjustOffsetX, proposedContentOffset.y);
}

这样我们要做的吸附效果的Layout文件就完成了。

我们在初始化UICollectionView的时候选择带有Layout参数的init方法即可。

UICollectionView *collectionView = [[UICollectionView alloc]initWithFrame:rect collectionViewLayout:viscosityLayout];

Demo地址:iOS_Demo-自定义UICollectionView的布局

Demo下载地址:iOS_Demo

注:把Demo中的ViewController.m的33行

UICollectionView *collectionView = [[UICollectionView alloc]initWithFrame:rect collectionViewLayout:viscosityLayout];

改成//具体初始化的逻辑已经实现了。

UICollectionView *collectionView = [[UICollectionView alloc]initWithFrame:rect collectionViewLayout:flowLayout];

即可实现下图所示的效果(cell滚动的时候,中间会慢慢变大,也有吸附效果,不过在最中心的cell才会吸附在中心),具体做法是在layoutAttributesForElementsInRect方法中修复了布局属性,可下载Demo自行查看。

uicollectionview_2.gif


作者:Darren

微博:@IT_攻城师

github:@Darren90

博客:http://www.cnblogs.com/fengtengfei/

欢迎您的访问...


转载于:https://www.cnblogs.com/fengtengfei/p/5100925.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值