collectionView技巧

  • 組頭、組尾
  • item的重排問題
  • sectionInset內(nèi)邊距
  • 自定義Layout
  • 第三方CHTCollectionViewWaterfallLayout的使用

組頭、組尾

//每段的段頭視圖,或者段尾視圖
-(UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
    if ([kind isEqualToString:UICollectionElementKindSectionHeader]) {
        HJCollectionReusableView *view = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"headerView" forIndexPath:indexPath];
        SWPWikiModel *wikiModel = self.dataSourceArray[indexPath.section];
        view.backgroundColor = [UIColor whiteColor];
        if ([wikiModel.kind isEqualToString:@"group"]) {
            view.kindLabel.text =  @"食物類別";
        }else if ([wikiModel.kind isEqualToString:@"brand"]) {
            view.kindLabel.text =  @"熱門品牌";
        }else if ([wikiModel.kind isEqualToString:@"restaurant"]) {
            view.kindLabel.text =  @"連鎖餐飲";
        }else{
            view.kindLabel.text =  @"其他類別";
        }
        
        return view;
    }else if ([kind isEqualToString:UICollectionElementKindSectionFooter]) {
        HJCollectionReusableView *view = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"footerView" forIndexPath:indexPath];
        view.backgroundColor = [UIColor colorWithRed:218/256.0 green:218/256.0 blue:218/256.0 alpha:1];
        view.kindLabel.backgroundColor = [UIColor colorWithRed:218/256.0 green:218/256.0 blue:218/256.0 alpha:1];
        return view;
    }
    return nil;
}

item的重排問題

  1. 添加長按手勢UILongpressGestureRecognizer
-(void)addLongPressGestureToCollectionView{
        UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc]initWithTarget:self      action:@selector(longPressHandle:)];
        [self.collectionView addGestureRecognizer:longPressGesture];
}
  1. 監(jiān)聽手勢狀態(tài)state變化
1.beginInteractiveMovementForItemAtIndexPath: //開始移動
2.updateInteractiveMovementTargetPosition:       //更新坐標
3.endInteractiveMovement:                                    //結(jié)束移動
4.cancelInteractiveMovement:                                //取消移動
  1. dataSourceArray刪除、添加數(shù)據(jù)
第三步:dataSourceArray刪除,插入數(shù)據(jù)
#pragma mark - Action
 /*cell的移動(從oldindex 移到 newindex)*/
 -(void)collectionView:(UICollectionView *)collectionView moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath: (NSIndexPath *)destinationIndexPath{
//0.獲取移動的起點和終點
       NSInteger from = sourceIndexPath.item;
       NSInteger to = destinationIndexPath.item;
       //1.獲取要刪除的數(shù)據(jù)
       NSString *o = self.datasourceArray[from];    
       //2.刪除要移動的數(shù)據(jù)
       [self.datasourceArray removeObjectAtIndex:from];    
       //3.插入指定的位置
       [self.datasourceArray insertObject:o atIndex:to];
}

sectionInset內(nèi)邊距

dd.png

自定義Layout

  1. 邊界改變是否讓布局無效
-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds{
    return YES;
}
  1. 準備布局
/*
 *注釋:第一步
 *  1.實例化時最開始調(diào)用這個方法,
 *  2.布局無效之后
 *  3.查詢布局信息之前
 *  4.如果子類覆蓋(重寫方法),子類應該總是調(diào)用super。invalidateLayout布局無效
 *  5.在這里面一般就是寫collectionView、cell。。配置信息(itemSize,間距等)
 */
-(void)prepareLayout
{
    [super prepareLayout];
    //滾動方向
    self.scrollDirection = UICollectionViewScrollDirectionVertical;
    //設置collectionView內(nèi)邊距
    CGFloat insert = (self.collectionView.frame.size.width - self.itemSize.width) / 2;
    self.sectionInset = UIEdgeInsetsMake(insert, insert, insert, insert);
}
  1. 返回滾動后推薦的停留點(偏移量)
/*
 *注釋:第二步
 *
 *返回滾動后推薦(proposed)停止的點(偏移量),在這里要進行處理
 */
-(CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{
    //計算最終顯示的邊界
    CGRect rect;
    rect.origin.x = proposedContentOffset.x;
    rect.origin.y = 0;
    rect.size = self.collectionView.frame.size;
    // 獲得所有顯示區(qū)域內(nèi)的布局對象
    NSArray *arr = [super layoutAttributesForElementsInRect:rect];
    // collectionView中心點的x值 、 偏移量 + 一半寬度 = 當前collectionView的中點對應著contentView的哪一個中點
    CGFloat contentCenterX = self.collectionView.frame.size.width / 2 + proposedContentOffset.x;
    //存放布局對象數(shù)組中離(上面計算的)的點最小間距的布局對象的距離
    CGFloat minDistance = MAXFLOAT;
    for (UICollectionViewLayoutAttributes * attr in arr) {
        CGFloat distance = ABS(attr.center.x - contentCenterX);
        minDistance = minDistance > distance ? distance : minDistance;
    }
    //處理推薦的點,達到每次都停在圖片中間的效果(之所以明確是?,因為偏移一定是負數(shù))
    proposedContentOffset.x += minDistance;
    return proposedContentOffset;
}
  1. 重新布局可視范圍視圖內(nèi)的所有子控件
/*
 *注釋:第三步:重新布局所有子控件cell
 *
 *作用相當于layoutSubViews,最后才執(zhí)行的
 */
-(NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
{
    //先布局super,只有流體布局才能使用
    NSArray *arr = [super layoutAttributesForElementsInRect:rect];
    
    //計算contentView中心點
    CGFloat contentCenterX = self.collectionView.contentOffset.x + self.collectionView.frame.size.width / 2;
    
    for (UICollectionViewLayoutAttributes *attr in arr) {
        //求contentView的中心點和cell的中心點的距離[ABS:取絕對值]
        CGFloat distance = ABS(attr.center.x - contentCenterX);//比不理解。。。。。。。。。。。。。。
        //根據(jù)間距,計算縮放比例,
        CGFloat scale = 1 - distance / self.collectionView.frame.size.width;
        //設置cell的顯示比例(當cell正好處于collectionView中點)
        attr.transform = CGAffineTransformMakeScale(scale, scale);
    }
    return arr;
}

第三方CHTCollectionViewWaterfallLayout的使用

  • 組頭、組尾
  • 必須實現(xiàn)的代理方法,確定itemSize
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
  UICollectionReusableView *reusableView = nil;

  if ([kind isEqualToString:CHTCollectionElementKindSectionHeader]) {
    reusableView = [collectionView dequeueReusableSupplementaryViewOfKind:kind
                                                      withReuseIdentifier:HEADER_IDENTIFIER
                                                             forIndexPath:indexPath];
  } else if ([kind isEqualToString:CHTCollectionElementKindSectionFooter]) {
    reusableView = [collectionView dequeueReusableSupplementaryViewOfKind:kind
                                                      withReuseIdentifier:FOOTER_IDENTIFIER
                                                             forIndexPath:indexPath];
  }

  return reusableView;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
  return [self.cellSizes[indexPath.item] CGSizeValue];
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

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

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