从0开始实现一个直播礼物系统

本文详细介绍了如何从头开始实现一个直播间的礼物系统,包括使用UICollectionView构建礼物列表,解决礼物排序问题,以及实现礼物动画效果展示。在动画效果中,通过自定义UICollectionViewFlowLayout和NSOperationQueue解决顺序和连击展示的问题,同时通过一个管理类JPGiftShowManager来处理礼物的逻辑。最后,文章讨论了如何实现连击、累加以及添加gif图等额外需求。
摘要由CSDN通过智能技术生成
  • 前段时间公司APP要对直播间的礼物系统进行改版,由于以前直播的收入不在于礼物分成,所以以前的礼物系统是很简单的一个展示而已.为适应主流直播间的礼物效果,特由此改版!

1. 所有直播间的礼物系统,第一步用户看到的无外乎都是礼物的列表界面

  • 纵观主流直播间的礼物列表应该都是使用UICollectionView实现的,所以我也不例外,下面就是各种撸代码.效果如下

  • 看着效果还不错吧.但是但是我突然发现一个问题.礼物展示的顺序跟我想要的顺序不一样,跟数据的排序也不一致.看图来说

  • 黄色的顺序是我们想要的顺序,但是现在顺序确是红色的.为什么呢?我们都知道collectionview的滚动方向是有layout控制的.代码如下
    UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
    layout.itemSize = CGSizeMake(itemW, itemH);
    layout.minimumLineSpacing = 0;
    layout.minimumInteritemSpacing = 0;
    layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
  • 看代码之后才明白,因为我们设置的滚动方向是横向滚动,所以系统会默认先把垂直方向的Item填充,然后再横向填充,这就不难解释为啥会是这种排序.如果换成垂直滚动呢?

  • 这样也不满足我们的需求,既然系统的不行,那么只有拿出独门武器,自定义一个flowlayout吧.让它按照我们的要求去滚动,去排序.
- (void)prepareLayout {
    //自定义layout都必须重写这个方法
    [super prepareLayout];

    //设置基本属性
    CGFloat itemW = SCREEN_WIDTH/4.0;
    CGFloat itemH = itemW*105/93.8;
    self.itemSize = CGSizeMake(itemW, itemH);
    self.minimumLineSpacing = 0;
    self.minimumInteritemSpacing = 0;
    self.scrollDirection = UICollectionViewScrollDirectionHorizontal;

    //刷新后清除所有已布局的属性 重新获取
    [self.cellAttributesArray removeAllObjects];

    NSInteger cellCount = [self.collectionView numberOfItemsInSection:0];
    for (NSInteger i = 0; i < cellCount; i++) {
        //取出每一个的Item的布局.重新赋值
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0];
        UICollectionViewLayoutAttributes *attibute = [self layoutAttributesForItemAtIndexPath:indexPath];
        NSInteger page = i / 8;//第几页
        NSInteger row = i % 4 + page*4;//第几列
        NSInteger col = i / 4 - page*2;//第几行
        attibute.frame = CGRectMake(row*itemW, col*itemH, itemW, itemH);
        //保存所有已经重新赋值的布局
        [self.cellAttributesArray addObject:attibute];
    }
}

- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect{
    //返回当前可见区域内的已经计算好的布局
    return self.cellAttributesArray;
}
  • 写出来之后心里沾沾自喜,这样应该可以实现了吧.看看效果吧


* 应该可以看出来问题了吧,我选中的那个礼物第一页和第二页竟然都出现了,我明明设置了分页滚动的呀.查看层级结构如下


* 原来是可爱的么么哒礼物被挤到外面了.由于没有设置弹簧的效果,所以没太注意少了一个礼物,那么原因呢? 想了好久才想起来是不是滚动的范围不够,导致么么哒不显示在界面中呢?又去扒了扒怎么设置自定义的layout的contentoffset.最终找到一个方法.

- (CGSize)collectionViewContentSize{

    NSInteger cellCount = [self.collectionView numberOfItemsInSection:0];
    NSInteger page = cellCount / 8 + 1;
    return CGSizeMake(SCREEN_WIDTH*page, 0);
}
  • 但是这样做真的可以么?看看效果吧

  • 到此为止基本实现了一个主流的礼物列表界面.关于礼物的点击逻辑看看代码就可以了.在此就不多啰嗦了.(详见代码 – JPGiftView)

2. 点击发送之后的礼物动画效果展示

  • 最简单的实现就是创建一个View在点击发送后把当前选中的礼物信息传入这个展示礼物效果的view中,写一个位移的动画进行展示.如果连送,那么就在view展示之前计算好一共连击多少次礼物,然后直接展示x几.如图


* 但是这样的弊端肯定是很多,比如我会将一个用户送其中一个礼物这样算成一个完整的实际的礼物.同一个用户送不同的礼物算是第二个完整的礼物.那么每一个完整的礼物都是唯一的存在.如果使用上面的逻辑来处理,那么你会发现出现各种让你忍俊不禁的bug,比如,不同礼物的累加,不同礼物会进行顶替正在展示的当前礼物…..
* 既然知道了bug的存在,那么怎么解决呢?首先我脑海中第一个想到的就是强大的队列,一个苹果帮我们封装好的面向对象的类 – NSOperationQueue .这样我们就可以将每一个完整的礼物当成一个操作 – NSOperation .加入队列中,这样就会自动按照顺序去执行礼物的展示.道理和逻辑都想通了,怎么实现是需要好好斟酌下咯!
* 俗话说代码是不会骗人的,当我将一个个操作加入到队列中的时候,又出bug.并没有按照我们设想的一个个按照排队的顺序去执行.(系统有个依赖方法,但是想了想不太能实现需求,也就没试)随后去Google了一下,才知道原来系统提供的API只能加入操作,并不能在上一个操作结束的时候再去执行下一个操作.如果需要按照顺序执行,就要自定义一个操作,然后在一个完整礼物礼物动画展示完成后结束当前操作,那么才会按顺序去执行下一个操作!
* 具体的代码可见 JPGiftOperation类
* 自定义操作的主要是改变操作的两个属性 下图所示,默认改为NO.使用@synthesize禁止系统的GET/SET,有开发者自己控制
* 我们需要重写star方法来创建操作(礼物动画的展示)

- (
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值