iOS- UICollectionView实现表情数据横排横滚动

87 篇文章 1 订阅

1.问题提出

        在开发即时通讯项目时会遇到一个需求,那就是开发一个表情键盘。这时候实现的方法有好多种,大部分人会考虑用UIScrollView实现,但是当表情有200个的时候,UIScrollView的button难道就要创建200个么?考虑到按钮重用的,自然想到UICollectionView。想实现表情数据横排横滚动,可能会遇到设置cell的数据源的坑。

笔者数据源文件.plist长这样:

 

当时这样设置过:

 

    UICollectionViewFlowLayout *layout = [UICollectionViewFlowLayout new];
    layout.scrollDirection = UICollectionViewScrollDirectionHorizontal; //横排滚动
    layout.itemSize = CGSizeMake(itemWidth, kOneItemHeight);

- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    YHExpressionAddCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell1" forIndexPath:indexPath];
    NSLog(@"%ld",(long)indexPath.item);
    if (indexPath.item < self.dataArray.count) {
        cell.model = self.dataArray[indexPath.item];
    }
    return cell;
}

 

我理想的界面是:           

       

但实际运行的界面:                           

  

   仔细想想,就是cellForItemAtIndexPath设置错误。那么如何正确地实现表情数据横排横滚动呢,请看下文。

 

2.解决方法

 

一:获取数据

变量:

kOnePageCount:一页显示的表情数量

emoticonGroupPageIndexs:各表情组起始页下标数组

emoticonGroupTotalPageCount:表情组总页数

 

情景:

假设一页显示20个表情,1个删除按钮。现在有两个表情组A,B.其中A有6页,B有2页

kOnePageCount = 20;

emoticonGroupPageIndexs = @[0,6];

emoticonGroupTotalPageCount = 8;

 

算法:

 

    _emoticonGroups = [YHExpressionHelper emoticonGroups];
   //获取各表情组起始页下标数组
    NSMutableArray *indexs = [NSMutableArray new];
    NSUInteger index = 0;
    for (YHEmoticonGroup *group in _emoticonGroups) {
        [indexs addObject:@(index)];
        NSUInteger count = ceil(group.emoticons.count / (float)kOnePageCount);
        if (count == 0) count = 1;
        index += count;
    }
    _emoticonGroupPageIndexs = indexs;
    
   //表情组总页数
    NSMutableArray *pageCounts = [NSMutableArray new];
    _emoticonGroupTotalPageCount = 0;
    for (YHEmoticonGroup *group in _emoticonGroups) {
        NSUInteger pageCount = ceil(group.emoticons.count / (float)kOnePageCount);
        if (pageCount == 0) pageCount = 1;
        [pageCounts addObject:@(pageCount)];
        _emoticonGroupTotalPageCount += pageCount;
    }
    _emoticonGroupPageCounts = pageCounts;

 

 

 

 

 

二:设置UICollectionView 数据源

 

//表情组总页数 (eg:有两个表情组A,B.其中A有6页,B有2页。则_emoticonGroupTotalPageCount = 8)
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    return _emoticonGroupTotalPageCount;
}

//一页显示的表情数量
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return kOnePageCount + 1; // “1”是删除按钮
}

//设置Cell
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    
    YHEmoticonCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];
    if (indexPath.row == kOnePageCount) {
        cell.isDelete = YES;
        cell.emoticon = nil;
    } else {
        cell.isDelete = NO;
        cell.emoticon = [self _emoticonForIndexPath:indexPath];
    }
    return cell;
}

- (YHEmoticon *)_emoticonForIndexPath:(NSIndexPath *)indexPath {
    NSUInteger section = indexPath.section;
    for (NSInteger i = _emoticonGroupPageIndexs.count - 1; i >= 0; i--) {
        NSNumber *pageIndex = _emoticonGroupPageIndexs[i];
        if (section >= pageIndex.unsignedIntegerValue) {
            YHEmoticonGroup *group = _emoticonGroups[i];
            NSUInteger page = section - pageIndex.unsignedIntegerValue;
            NSUInteger index = page * kOnePageCount + indexPath.row;
            
            // transpose line/row
            NSUInteger ip = index / kOnePageCount;
            NSUInteger ii = index % kOnePageCount;
            NSUInteger reIndex = (ii % 3) * 7 + (ii / 3);
            index = reIndex + ip * kOnePageCount;
            
            if (index < group.emoticons.count) {
                return group.emoticons[index];
            } else {
                return nil;
            }
        }
    }
    return nil;
}


DuangDuang,成功运行并显示出我想要的界面。

另外可以参考我的Demo:(喜欢的点个赞哦O(∩_∩)O哈哈哈~)

 

仿微信表情键盘

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值