美文网首页iOS Development
UICollectionView+UIPageControl实现

UICollectionView+UIPageControl实现

作者: Claire_wu | 来源:发表于2018-01-19 15:06 被阅读366次

    1 实现效果

    楼组在项目过程中遇到这么一个需求,实现一个UICollectionView+UIPageControl实现分页。UI截图如下:


    image.png

    2 实现思路

    2.1 item个数

    collectionView实现分页效果,有一个要点要注意的是item的个数。比如要实现collectionView一页只有一行,且最多放三个元素,那么numberOfItemsInSection方法就应该如下这么写,具体缘由读者们可以自己思考下哦😁。

    - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
        NSInteger num = ceilf(self.dataList.count/3.0)*3;
        return num;
    }
    

    2.2 自定义layout

    自定义一个layout,实现自定义layoutDelegate里的collectionView:layout:cellCenteredAtIndexPath:page:方法。这个layout是我在网上找的大牛写的,无论你的需求是一页要展示几个item,一页要展示几行,均可以使用,下面贴出源码:

    #import <UIKit/UIKit.h>
    
    @protocol HAHorizontalCollectionFlowLayoutDelegate
    
    - (void)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout cellCenteredAtIndexPath:(NSIndexPath *)indexPath page:(int)page;
    
    @end
    
    @interface HAHorizontalCollectionFlowLayout : UICollectionViewFlowLayout
    // 一行中 cell的个数
    @property (nonatomic,assign) NSUInteger itemCountPerRow;
    // 一页显示多少行
    @property (nonatomic,assign) NSUInteger rowCount;
    
    @property (nonatomic,weak)   id<HAHorizontalCollectionFlowLayoutDelegate> delegate;
    @end
    
    #import "HAHorizontalCollectionFlowLayout.h"
    
    @interface HAHorizontalCollectionFlowLayout()
    @property (strong, nonatomic) NSMutableArray *allAttributes;
    @end
    
    @implementation HAHorizontalCollectionFlowLayout
    
    - (void)prepareLayout
    {
        
        [super prepareLayout];
        
        self.allAttributes = [NSMutableArray array];
        
        NSUInteger count = [self.collectionView numberOfItemsInSection:0];
        for (NSUInteger i = 0; i<count; i++) {
            NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
            UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForItemAtIndexPath:indexPath];
            [self.allAttributes addObject:attributes];
        }
    }
    
    - (CGSize)collectionViewContentSize
    {
        return [super collectionViewContentSize];
    }
    
    - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
        return YES;
    }
    
    - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
    {
        NSUInteger item = indexPath.item;
        NSUInteger x;
        NSUInteger y;
        [self targetPositionWithItem:item resultX:&x resultY:&y];
        NSUInteger item2 = [self originItemAtX:x y:y];
        NSIndexPath *theNewIndexPath = [NSIndexPath indexPathForItem:item2 inSection:indexPath.section];
        
        UICollectionViewLayoutAttributes *theNewAttr = [super layoutAttributesForItemAtIndexPath:theNewIndexPath];
        theNewAttr.indexPath = indexPath;
        return theNewAttr;
    }
    
    - (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
    {
        NSArray *attributes = [super layoutAttributesForElementsInRect:rect];
        
        CGRect visibleRect;
        visibleRect.origin = self.collectionView.contentOffset;
        visibleRect.size = self.collectionView.bounds.size;
        
        NSMutableArray *tmp = [NSMutableArray array];
        
        for (UICollectionViewLayoutAttributes *attr in attributes) {
            
            if (CGRectIntersectsRect(attr.frame, rect)) {
                if (visibleRect.origin.x == 0) {
                    [self.delegate collectionView:self.collectionView layout:self cellCenteredAtIndexPath:attr.indexPath page:0];
                }else{
                    // 除法取整 取余数
                    div_t x = div(visibleRect.origin.x,visibleRect.size.width);
                    if (x.quot > 0 && x.rem > 0) {
                        [self.delegate collectionView:self.collectionView layout:self cellCenteredAtIndexPath:attr.indexPath page:x.quot + 1];
                    }
                    if (x.quot > 0 && x.rem == 0) {
                        [self.delegate collectionView:self.collectionView layout:self cellCenteredAtIndexPath:attr.indexPath page:x.quot];
                    }
                }
            }
            
            for (UICollectionViewLayoutAttributes *attr2 in self.allAttributes) {
                if (attr.indexPath.item == attr2.indexPath.item) {
                    [tmp addObject:attr2];
                    break;
                }
            }
        }
        return tmp;
    }
    
    // 根据 item 计算目标item的位置
    // x 横向偏移  y 竖向偏移
    - (void)targetPositionWithItem:(NSUInteger)item
                           resultX:(NSUInteger *)x
                           resultY:(NSUInteger *)y
    {
        NSUInteger page = item/(self.itemCountPerRow*self.rowCount);
        
        NSUInteger theX = item % self.itemCountPerRow + page * self.itemCountPerRow;
        NSUInteger theY = item / self.itemCountPerRow - page * self.rowCount;
        if (x != NULL) {
            *x = theX;
        }
        if (y != NULL) {
            *y = theY;
        }
    }
    
    // 根据偏移量计算item
    - (NSUInteger)originItemAtX:(NSUInteger)x
                              y:(NSUInteger)y
    {
        NSUInteger item = x * self.rowCount + y;
        return item;
    }
    
    @end
    

    相关文章

      网友评论

        本文标题:UICollectionView+UIPageControl实现

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