zoukankan      html  css  js  c++  java
  • 【iOS系列】- iOS吸附效果的实现 之 UICollectionView的使用全解

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

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

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

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

    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自行查看。


    作者:Darren

    微博:@IT_攻城师

    github:@Darren90

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

    欢迎您的访问...


  • 相关阅读:
    【常用配置】Spring框架web.xml通用配置
    3.从AbstractQueuedSynchronizer(AQS)说起(2)——共享模式的锁获取与释放
    2.从AbstractQueuedSynchronizer(AQS)说起(1)——独占模式的锁获取与释放
    1.有关线程、并发的基本概念
    0.Java并发包系列开篇
    SpringMVC——DispatcherServlet的IoC容器(Web应用的IoC容器的子容器)创建过程
    关于String的问题
    Spring——Web应用中的IoC容器创建(WebApplicationContext根应用上下文的创建过程)
    <<、>>、>>>移位操作
    System.arraycopy(src, srcPos, dest, destPos, length) 与 Arrays.copyOf(original, newLength)区别
  • 原文地址:https://www.cnblogs.com/fengtengfei/p/5100925.html
Copyright © 2011-2022 走看看