美文网首页
collectionView技巧

collectionView技巧

作者: Hyman0819 | 来源:发表于2016-11-18 19:41 被阅读210次
    • 组头、组尾
    • item的重排问题
    • sectionInset内边距
    • 自定义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. 监听手势状态state变化
    1.beginInteractiveMovementForItemAtIndexPath: //开始移动
    2.updateInteractiveMovementTargetPosition:       //更新坐标
    3.endInteractiveMovement:                                    //结束移动
    4.cancelInteractiveMovement:                                //取消移动
    
    1. dataSourceArray删除、添加数据
    第三步:dataSourceArray删除,插入数据
    #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.获取要删除的数据
           NSString *o = self.datasourceArray[from];    
           //2.删除要移动的数据
           [self.datasourceArray removeObjectAtIndex:from];    
           //3.插入指定的位置
           [self.datasourceArray insertObject:o atIndex:to];
    }
    

    sectionInset内边距

    dd.png

    自定义Layout

    1. 边界改变是否让布局无效
    -(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds{
        return YES;
    }
    
    1. 准备布局
    /*
     *注释:第一步
     *  1.实例化时最开始调用这个方法,
     *  2.布局无效之后
     *  3.查询布局信息之前
     *  4.如果子类覆盖(重写方法),子类应该总是调用super。invalidateLayout布局无效
     *  5.在这里面一般就是写collectionView、cell。。配置信息(itemSize,间距等)
     */
    -(void)prepareLayout
    {
        [super prepareLayout];
        //滚动方向
        self.scrollDirection = UICollectionViewScrollDirectionVertical;
        //设置collectionView内边距
        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;
        // 获得所有显示区域内的布局对象
        NSArray *arr = [super layoutAttributesForElementsInRect:rect];
        // collectionView中心点的x值 、 偏移量 + 一半宽度 = 当前collectionView的中点对应着contentView的哪一个中点
        CGFloat contentCenterX = self.collectionView.frame.size.width / 2 + proposedContentOffset.x;
        //存放布局对象数组中离(上面计算的)的点最小间距的布局对象的距离
        CGFloat minDistance = MAXFLOAT;
        for (UICollectionViewLayoutAttributes * attr in arr) {
            CGFloat distance = ABS(attr.center.x - contentCenterX);
            minDistance = minDistance > distance ? distance : minDistance;
        }
        //处理推荐的点,达到每次都停在图片中间的效果(之所以明确是➕,因为偏移一定是负数)
        proposedContentOffset.x += minDistance;
        return proposedContentOffset;
    }
    
    1. 重新布局可视范围视图内的所有子控件
    /*
     *注释:第三步:重新布局所有子控件cell
     *
     *作用相当于layoutSubViews,最后才执行的
     */
    -(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);//比不理解。。。。。。。。。。。。。。
            //根据间距,计算缩放比例,
            CGFloat scale = 1 - distance / self.collectionView.frame.size.width;
            //设置cell的显示比例(当cell正好处于collectionView中点)
            attr.transform = CGAffineTransformMakeScale(scale, scale);
        }
        return arr;
    }
    

    第三方CHTCollectionViewWaterfallLayout的使用

    • 组头、组尾
    • 必须实现的代理方法,确定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];
    }
    

    相关文章

      网友评论

          本文标题:collectionView技巧

          本文链接:https://www.haomeiwen.com/subject/ijdspttx.html