iOS UICollectionViewCell的一種佈局

zhf_Zachariah發表於2017-12-13

重寫UICollectionView的FlowLayout佈局

- (instancetype)init{
    if (self = [super init]) {
        self.itemSize = CGSizeMake(kScreenWidth / 2, kScreenHeight / 2 - 49 - 30);
        self.minimumLineSpacing = 2;
        self.minimumInteritemSpacing = 2;
        self.sectionInset = UIEdgeInsetsMake(2, 2, 2, 2);
    }
    return self;
}
/**
 *  collectionView的顯示範圍發生改變的時候,呼叫下面這個方法是否重新重新整理
 *
 *  @param newBounds
 *
 *  @return 是否重新重新整理
 */
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
    return YES;
}
/**
 *  佈局的初始化操作
 */
- (void)prepareLayout
{
    [super prepareLayout];
    // 設定為水平滾動
    self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
    // 設定內邊距
    CGFloat insetGap = (self.collectionView.frame.size.width - self.itemSize.width) * 0.5;
    self.sectionInset = UIEdgeInsetsMake(0, insetGap, 0, insetGap);
}
/**
 *  設定cell的顯示大小
 *
 *  @param rect 範圍
 *
 *  @return 返回所有元素的佈局
 */
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
    // 獲取計算好的佈局屬性
    NSArray *arr = [[NSArray alloc]initWithArray:[super layoutAttributesForElementsInRect:rect] copyItems:YES];
    for (int i = 0; i < arr.count; i ++) {
        UICollectionViewLayoutAttributes *att = arr[i];
        //算比例
        //拿到每個item的位置  算出itemCenterX  和collectionCenterX 的一個距離
        CGFloat distance = ABS(att.center.x - self.collectionView.frame.size.width * 0.5 - self.collectionView.contentOffset.x);
        CGFloat scale = 0.5;
        CGFloat w = (self.collectionView.frame.size.width + self.itemSize.width) * 0.5;
        if (distance >= w) {
            scale = 0.5;
        }else{
            scale = scale +  (1- distance / w ) * 0.5;
        }
        att.transform = CGAffineTransformMakeScale(scale, scale);
    }
    return arr;
}
//滑動完成後,會來到此方法 - 線性滑動
//proposedContentOffset  最後停止的 contentOffset
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{
    //proposedContentOffset 滑動之後最後停的位置
    CGRect  rect;
    rect.origin = proposedContentOffset;
    rect.size = self.collectionView.frame.size;
    //獲取停止時,顯示的cell的frame
    //NSArray *tempArray  = [super  layoutAttributesForElementsInRect:rect];
    NSArray *tempArray = [[NSArray alloc]initWithArray:[super layoutAttributesForElementsInRect:rect] copyItems:YES];
    CGFloat  gap = 1000;
    CGFloat  a = 0;
    for (int i = 0; i < tempArray.count; i++) {
        //判斷和中心的距離,得到最小的那個
        if (gap > ABS([tempArray[i] center].x - proposedContentOffset.x - self.collectionView.frame.size.width * 0.5)) {
            gap =  ABS([tempArray[i] center].x - proposedContentOffset.x - self.collectionView.frame.size.width * 0.5);
            a = [tempArray[i] center].x - proposedContentOffset.x - self.collectionView.frame.size.width * 0.5;
        }
    }
    CGPoint  point  =CGPointMake(proposedContentOffset.x + a , proposedContentOffset.y);
    return point;
}

複製程式碼

動畫效果.gif

相關文章