UICollectionView自定義相冊

效果圖

Untitled11卡片動畫1.gif

一.我們要對UICollectionView的布局進(jìn)行自定義

這是我自定義的宏以及靜態(tài)變量

#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即可

    布局的設(shè)置(重點(diǎn))
    UICollectionViewFlowLayout 繼承它就擁有流水的效果
    UICollectionViewLayout 如果繼承它,那么一切布局要從頭開始
    下面我們就重點(diǎn)講講自定義布局的里面一些知識點(diǎn),我就以我布局的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之后進(jìn)行走的
     */
    -(void)prepareLayout
    {
        //設(shè)置格子的大小
        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;
    
       /**
        *  設(shè)置滑動方向
        *  UICollectionViewScrollDirectionHorizontal 水平方向
        *  UICollectionViewScrollDirectionVertical   垂直方向
        */
       self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
      /*
        //        //設(shè)置最小行間距
        //        self.minimumLineSpacing = 10;
        //
        //        //設(shè)置最小列間距
        //        self.minimumInteritemSpacing = 10;
        //
        //        //設(shè)置與四周的邊距
        //        self.sectionInset = UIEdgeInsetsMake(5, 5, 5, 5);
    
       */
    
       /**
        *  每一個cell(item)都有自己的UICollectionViewLayoutAttributes
        *  每一個indexPath都有自己的UICollectionViewLayoutAttributes
        */
    }
    
    /**
     *  用來設(shè)置collectionView停止?jié)L動那一刻的位置
     *
     *  @param proposedContentOffset collectionView原本停留的位置
     *  @param velocity              滾動的速度
     */
    -(CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
    {
        //1.計(jì)算scrollview最后會停留的范圍
        CGRect lastRect;
        lastRect.origin = proposedContentOffset;
        lastRect.size = self.collectionView.frame.size;
    
        //計(jì)算屏幕最中間的x
        CGFloat centerX = proposedContentOffset.x + self.collectionView.frame.size.width*0.5;
    
      //2.取出這個范圍內(nèi)的所有屬性
      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的滾動進(jìn)行實(shí)時監(jiān)控
     *  只要顯示的便捷發(fā)生改變就進(jìn)行重新布局,內(nèi)部會重新調(diào)用 layoutAttributesForElementsInRect:(CGRect)rect,獲得所有cell的布局屬性
     */
    -(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
    {
        return YES;
    }
    
     /**
      *  對傳進(jìn)來的item進(jìn)行監(jiān)聽
      */
     -(NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
     {
       //計(jì)算呢可見的矩形框
       CGRect visiableRect;
    
      visiableRect.size = self.collectionView.frame.size;
      visiableRect.origin = self.collectionView.contentOffset;
      //1.取出默認(rèn)的cell的 UICollectionViewLayoutAttributes,super是返回所有的圖片
      NSArray *array = [super layoutAttributesForElementsInRect:rect];
    
     //計(jì)算屏幕最中間的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中點(diǎn)的x
      CGFloat itemCenterX = attributes.center.x;
      
      //根據(jù)屏幕最中間的距離計(jì)算縮放比例,差距越小縮放比例越大
      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(掛代理,遵守協(xié)議)
      <UICollectionViewDataSource,UICollectionViewDelegate>
  /**
   *   UICollectionView的創(chuàng)建
   */
   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的代理方法的實(shí)現(xiàn)
-(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的點(diǎn)擊事件
 */
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
    //刪除模型數(shù)據(jù)(刪除的指定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 圖片數(shù)組化
-(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

實(shí)例2旋轉(zhuǎn)相冊 密碼:hwh3

旋轉(zhuǎn)相冊

值得注意的是layout的一個屬性

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

實(shí)例3.圓形角度相冊 密碼: yj7w

圓形角度相冊.gif

大總結(jié):在進(jìn)行l(wèi)ayout 進(jìn)行布局時記住如下幾點(diǎn):

  • 1.繼承方式

    UICollectionViewFlowLayout 繼承它就擁有流水的效果
    UICollectionViewLayout 如果繼承它,那么一切布局要從頭開始

  • 2.在第二種繼承方式里面layout重新布局的類.m中不可缺少的方法(一般來說這3個方法不可缺少)

    /**
     *  對collection的滾動進(jìn)行實(shí)時監(jiān)控
     *  只要顯示的便捷發(fā)生改變就進(jìn)行重新布局,內(nèi)部會重新調(diào)用 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;
    }
    //在此里面進(jìn)行自己想要的設(shè)置
    -(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;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容