1. 程式人生 > 實用技巧 >UICollectionView 03 - 卡片式佈局篇

UICollectionView 03 - 卡片式佈局篇

  • 初始化操作(prepareLayou)

    - (void)prepareLayout {
        //設定每個item的大小  這個屬性最好在控制器中設定
        self.itemSize = CGSizeMake(150, 150);
        //設定滾動方向
        self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
        //設定內邊距
        CGFloat insert =(self.collectionView.frame.size.width-self.itemSize.width)/2;
        self.sectionInset 
    =UIEdgeInsetsMake(0, insert, 0, insert); //設定每行的最小間距 self.minimumLineSpacing = 50.0; }
  • item(滑停居中)

    1.只要手一鬆開就會呼叫

    2.這個方法的返回值,就決定了CollectionView停止滾動時的偏移量

    3.proposedContentOffset這個是最終的偏移量的值但是實際的情況還是要根據返回值來定

    4.velocity是滾動速率有個x和y如果x有值說明x上有速度

    5.如果y有值說明y上又速度還可以通過x或者y的正負來判斷是左還是右(上還是下滑動) 有時候會有用

    -(CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity{
        
    //計算出 最終顯示的矩形框 CGRect rect; rect.origin.x =proposedContentOffset.x; rect.origin.y=0; rect.size=self.collectionView.frame.size;
        NSArray * array = [super layoutAttributesForElementsInRect:rect];
    
        // 計算CollectionView最中心點的x值 這裡要求 最終的 要考慮慣性
        CGFloat centerX = self.collectionView.frame.size.width /2
    + proposedContentOffset.x; //存放的最小間距 CGFloat minDelta = MAXFLOAT; for (UICollectionViewLayoutAttributes * attrs in array) { if (ABS(minDelta)>ABS(attrs.center.x-centerX)) { minDelta=attrs.center.x-centerX; } } // 修改原有的偏移量 proposedContentOffset.x+=minDelta; //如果返回的時zero 那個滑動停止後 就會立刻回到原地 return proposedContentOffset; }
  • item(縮放)

    1.這個方法的返回值是一個數組(數組裡存放在rect範圍內所有元素的佈局屬性)

    2.這個方法的返回值 決定了rect範圍內所有元素的排布(frame)

    - (NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {
       //獲得super已經計算好的佈局屬性 只有線性佈局才能使用
           NSArray * array = [super layoutAttributesForElementsInRect:rect];
           //計算CollectionView最中心的x值
       #warning 特別注意:
           CGFloat centetX = self.collectionView.contentOffset.x + self.collectionView.frame.size.width/2;
           for (UICollectionViewLayoutAttributes * attrs in array) {
            //CGFloat scale = arc4random_uniform(100)/100.0;
              //attrs.indexPath.item 表示 這個attrs對應的cell的位置
               NSLog(@" 第%zdcell--距離:%.1f",attrs.indexPath.item ,attrs.center.x - centetX);
               //cell的中心點x 和CollectionView最中心點的x值
              CGFloat delta = ABS(attrs.center.x - centetX);
               //根據間距值  計算cell的縮放的比例
               //這裡scale 必須要 小於1
               CGFloat scale = 1 - delta/self.collectionView.frame.size.width;
               //設定縮放比例
               attrs.transform=CGAffineTransformMakeScale(scale, scale);
           }
           return array;
    }
  • 劃出範圍重新整理佈局

    多次呼叫只要滑出範圍就會呼叫

    CollectionView的顯示範圍發生改變的時候,是否重新發生布局

    一旦重新重新整理佈局,就會重新呼叫

    ·layoutAttributesForElementsInRect:方法

    ·preparelayout方法

    -(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
        return YES;
    }
  • demo
    卡片式佈局篇