UICollectionView自定义相册

作者: IIronMan | 来源:发表于2016-10-07 14:55 被阅读501次

    效果图

    Untitled11卡片动画1.gif

    一.我们要对UICollectionView的布局进行自定义

    这是我自定义的宏以及静态变量

    #define WIDTH  [UIScreen mainScreen].bounds.size.width
    #define Height [UIScreen mainScreen].bounds.size.height
    #define CWColor(a,b,c) [UIColor colorWithRed:(a)/255.0 green:(b)/255.0 blue:(c)/255.0 alpha:1.0]
    /**
     *   static 表示只在此文件里可以访问(防止其他文件访问) const防止别人去改
     */
    static NSString *const ID = @"cellID";
    
    • 1.自定义布局,集成UICollectionViewFlowLayout即可

      布局的设置(重点)
      UICollectionViewFlowLayout 继承它就拥有流水的效果
      UICollectionViewLayout 如果继承它,那么一切布局要从头开始
      下面我们就重点讲讲自定义布局的里面一些知识点,我就以我布局的CWLineLayout为例

      #import "CwLineLayout.h"
      #define WIDTH  [UIScreen mainScreen].bounds.size.width
      #define Height [UIScreen mainScreen].bounds.size.height
      
      static const CGFloat CWItemH = 120;
      @implementation CwLineLayout
      
      -(instancetype)init
      {
          self = [super init];
      
          if (self) {
        
        }
         return self;
      }
      
      /**
       *  此方法可在collectionView之后进行走的
       */
      -(void)prepareLayout
      {
          //设置格子的大小
          self.itemSize = CGSizeMake(CWItemH, CWItemH);
      
          CGFloat inset = (self.collectionView.frame.size.width-CWItemH)*0.5;
      
          self.sectionInset = UIEdgeInsetsMake(0, inset, 0, inset);
      
          self.minimumLineSpacing = 100;
      
         /**
          *  设置滑动方向
          *  UICollectionViewScrollDirectionHorizontal 水平方向
          *  UICollectionViewScrollDirectionVertical   垂直方向
          */
         self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
        /*
          //        //设置最小行间距
          //        self.minimumLineSpacing = 10;
          //
          //        //设置最小列间距
          //        self.minimumInteritemSpacing = 10;
          //
          //        //设置与四周的边距
          //        self.sectionInset = UIEdgeInsetsMake(5, 5, 5, 5);
      
         */
      
         /**
          *  每一个cell(item)都有自己的UICollectionViewLayoutAttributes
          *  每一个indexPath都有自己的UICollectionViewLayoutAttributes
          */
      }
      
      /**
       *  用来设置collectionView停止滚动那一刻的位置
       *
       *  @param proposedContentOffset collectionView原本停留的位置
       *  @param velocity              滚动的速度
       */
      -(CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
      {
          //1.计算scrollview最后会停留的范围
          CGRect lastRect;
          lastRect.origin = proposedContentOffset;
          lastRect.size = self.collectionView.frame.size;
      
          //计算屏幕最中间的x
          CGFloat centerX = proposedContentOffset.x + self.collectionView.frame.size.width*0.5;
      
        //2.取出这个范围内的所有属性
        NSArray *array1 = [self layoutAttributesForElementsInRect:lastRect];
      
        //遍历所有的属性
        CGFloat adjustOffsetX = MAXFLOAT;
      
        for (UICollectionViewLayoutAttributes *array2 in array1) {
        
        if (ABS(array2.center.x - centerX) < ABS(adjustOffsetX)) {
            
            adjustOffsetX = array2.center.x - centerX;
        }
       }
         return CGPointMake(proposedContentOffset.x+adjustOffsetX, proposedContentOffset.y);
       }
      
      /**
       *  对collection的滚动进行实时监控
       *  只要显示的便捷发生改变就进行重新布局,内部会重新调用 layoutAttributesForElementsInRect:(CGRect)rect,获得所有cell的布局属性
       */
      -(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
      {
          return YES;
      }
      
       /**
        *  对传进来的item进行监听
        */
       -(NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
       {
         //计算呢可见的矩形框
         CGRect visiableRect;
      
        visiableRect.size = self.collectionView.frame.size;
        visiableRect.origin = self.collectionView.contentOffset;
        //1.取出默认的cell的 UICollectionViewLayoutAttributes,super是返回所有的图片
        NSArray *array = [super layoutAttributesForElementsInRect:rect];
      
       //计算屏幕最中间的x
      
       CGFloat centerX = self.collectionView.contentOffset.x + self.collectionView.frame.size.width*0.5;
      
       //2.遍历所有的布局属性
        for (UICollectionViewLayoutAttributes *attributes in array) {
        
        if (!CGRectIntersectsRect(visiableRect, attributes.frame))
        {
            continue;
        }
      
        //每一个item中点的x
        CGFloat itemCenterX = attributes.center.x;
        
        //根据屏幕最中间的距离计算缩放比例,差距越小缩放比例越大
        CGFloat scale = 1+ 1 - ABS(itemCenterX - centerX)/(self.collectionView.frame.size.width*0.5);
      
        attributes.transform3D = CATransform3DMakeScale(scale, scale, scale);
       }
      
       return array;
      }
       @end
      
      • 2.建立UICollectionView(挂代理,遵守协议)
        <UICollectionViewDataSource,UICollectionViewDelegate>
      /**
       *   UICollectionView的创建
       */
       UICollectionView *collectionView = [[UICollectionView alloc]initWithFrame:CGRectMake(0, 100, WIDTH, WIDTH) collectionViewLayout:layout];
       collectionView.backgroundColor = CWColor(255, 255, 0);
       collectionView.showsHorizontalScrollIndicator = NO;
    
       collectionView.delegate = self;
       collectionView.dataSource = self;
       /**
        *  注册UICollectionView
        */
      [collectionView registerNib:[UINib nibWithNibName:@"CWImageCell" bundle:nil] forCellWithReuseIdentifier:ID];
      [self.view addSubview: collectionView];
    

    3.CollectionView的代理方法

     #pragma mark  collectionView的代理方法的实现
    -(NSInteger )collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
    {
        return self.imageArray.count;
    }
    
    -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
    {
    
    CWImageCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ID forIndexPath:indexPath];
    
    cell.imageName = self.imageArray[indexPath.item];
    
    cell.number.text = [NSString stringWithFormat:@"%ld",(long)indexPath.item+1];
    
    return cell;
    
    }
    
    /**
     *  collectionView的点击事件
     */
    -(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
    {
        //删除模型数据(删除的指定item)
        [self.imageArray removeObjectAtIndex:indexPath.item];
    
        //刷新UI
        [collectionView deleteItemsAtIndexPaths:@[indexPath]];
    
    }
    
    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
    /**
     *  动画式切换
     */
    if ([self.collectionView.collectionViewLayout isKindOfClass:[CwLineLayout class]]) {
        
        [self.collectionView setCollectionViewLayout:[[UICollectionViewFlowLayout alloc]init] animated:YES];
      }else
      {
           [self.collectionView setCollectionViewLayout:[[CwLineLayout alloc]init] animated:YES];
      }
    }
    #pragma mark 图片数组化
    -(NSMutableArray *)imageArray
    {
       if (!_imageArray) {
        
        _imageArray = [[NSMutableArray alloc]init];
        
        for (int i = 1; i <= 13 ; i++) {
            
            [_imageArray addObject:[NSString stringWithFormat:@"%d.jpg",i]];
        }
     }
      return _imageArray;
    }
    

    简单的相册demo 密码: fm69

    实例2旋转相册 密码:hwh3

    旋转相册

    值得注意的是layout的一个属性

    // zIndex越大,就越在上面
    attrs.zIndex = [self.collectionView numberOfItemsInSection:indexPath.section] - indexPath.item;
    

    实例3.圆形角度相册 密码: yj7w

    圆形角度相册.gif

    大总结:在进行layout 进行布局时记住如下几点:

    • 1.继承方式

      UICollectionViewFlowLayout 继承它就拥有流水的效果
      UICollectionViewLayout 如果继承它,那么一切布局要从头开始

    • 2.在第二种继承方式里面layout重新布局的类.m中不可缺少的方法(一般来说这3个方法不可缺少)

      /**
       *  对collection的滚动进行实时监控
       *  只要显示的便捷发生改变就进行重新布局,内部会重新调用 layoutAttributesForElementsInRect:(CGRect)rect,获得所有cell的布局属性
       */
      -(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
      {
            return YES;
      }
      
      /**
       *  位置改变就重新布局
       */
      -(NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
      {
         NSMutableArray *array = [NSMutableArray array];
      
         NSInteger count = [self.collectionView numberOfItemsInSection:0];
      
        for (int i = 0; i < count; i++) {
       
            UICollectionViewLayoutAttributes *attrs = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:i inSection:0]];
       
            [array addObject:attrs];
         }
        return array;
      }
      //在此里面进行自己想要的设置
      -(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
      {
         UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
         attrs.size = CGSizeMake(50,50);
         attrs.zIndex = indexPath.item;
         return attrs;
      }
      

    提示: UICollectionView 滚动条去掉

      垂直滚动条
      XXX.showsVerticalScrollIndicator = NO;
      水平滚动条
      XXX.showsHorizontalScrollIndicator = NO;

    相关文章

      网友评论

      本文标题:UICollectionView自定义相册

      本文链接:https://www.haomeiwen.com/subject/gsfyyttx.html