UICollectionView自定义相册

效果图

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;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容