横向分页滚动的UICollectionView,cell左右排版

做IMl聊天,实现自定义表情功能的时候,需要实现微信聊天时那样的表情排版,主要要实现collectionView能横向滑动cell左右排版。默认的cell排版方向是跟随滚动方向的,例如竖向滚动的话,cell的排版是从左到右、从上到下;横向滚动的话,cell是从上到下、然后从左到右。那么要实现collectionView横向滚动,cell从左到右、从上到下的排版,只需要自定义重写下collectionView的layout。自定义的layout代码如下:

#import 

@interface QQIMEmotionsCollectionViewFlowLayout : UICollectionViewFlowLayout

//  一行中 cell 的个数
@property (nonatomic,assign) NSUInteger itemCountPerRow;

//    一页显示多少行
@property (nonatomic,assign) NSUInteger rowCount;

@end
#import "QQIMEmotionsCollectionViewFlowLayout.h"

@interface QQIMEmotionsCollectionViewFlowLayout () 
@property (strong, nonatomic) NSMutableArray *allAttributes;

@end

@implementation QQIMEmotionsCollectionViewFlowLayout

-(instancetype)init
{
    if (self = [super init])
    {
        
    }
    return self;
}

- (void)prepareLayout
{
    [super prepareLayout];
    
    self.allAttributes = [NSMutableArray array];
    
    NSInteger sections = [self.collectionView numberOfSections];
    for (int i = 0; i < sections; i++)
    {
        NSMutableArray * tmpArray = [NSMutableArray array];
        NSUInteger count = [self.collectionView numberOfItemsInSection:i];
        
        for (NSUInteger j = 0; j *)layoutAttributesForElementsInRect:(CGRect)rect
{
    NSArray *attributes = [super layoutAttributesForElementsInRect:rect];
    
    NSMutableArray *tmp = [NSMutableArray array];
    
    for (UICollectionViewLayoutAttributes *attr in attributes) {
        for (NSMutableArray *attributes in self.allAttributes)
        {
            for (UICollectionViewLayoutAttributes *attr2 in attributes) {
                if (attr.indexPath.item == attr2.indexPath.item) {
                    [tmp addObject:attr2];
                    break;
                }
            }
            
        }
    }
    return tmp;
}


- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
    return YES;
}

// 根据 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
这个代码来自网上,其实实现原理我还没研究清楚,等我弄明白了,我会添加注释说明。另外,当collectionView的row数不是itemCountPerRow*rowCount的整数倍时,直接用会有问题。我的就出现了这个情况,下面我给出我生成collectionView的代码,我这样处理的话能让界面正常显示。

itemCountPerRow = 7,rowCount = 3。

-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
    int count ;
    if (self.emotionsArray.count%21) {
        count = (int)self.emotionsArray.count/21 + 1;
    }else{
        count = (int)self.emotionsArray.count/21;
    }
    return count * 21;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    QQIMEmotionsCollectionViewCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"emotions_id" forIndexPath:indexPath];
    if (indexPath.row < _emotionsArray.count) {
        [cell updateEmotionsCell:_emotionsArray[indexPath.row]];
    }else{
        [cell updateEmotionsCell:@""];
    }
    return cell;
}


你可能感兴趣的:(iOS开发,iOS开发)