XZ_iOS之自定义弹幕的实现

实现的效果图
这里写图片描述

弹幕(barrage),顾名思义是指子弹多而形成的幕布,大量吐槽评论从屏幕飘过时效果看上去像是飞行射击游戏里的弹幕。——来自百度百科
弹幕的特点
1、弹幕可以循环播放
2、弹幕的速度不同
3、弹幕是随机出现的

弹幕的肢解分析
这里写图片描述

弹幕的自动追加的重要的三个节点
1、创建弹幕view开始的时间
2、弹幕view完全进入屏幕
3、弹幕view完全飞出屏幕

初始化弹幕,随机分配弹幕轨迹

// 弹道数组
    NSMutableArray *trajectorys = [NSMutableArray arrayWithArray:@[@(0),@(1),@(2),@(3)]];
    for (int i = 0; i < 4; i++) { // < trajectorys.count
        if (self.bulletComments.count > 0) {
            // 通过随机数获取弹幕的轨迹
            NSInteger index = arc4random()%trajectorys.count;
            int trajectory = [[trajectorys objectAtIndex:index] intValue];
            [trajectorys removeObjectAtIndex:index];
            // 从弹幕数组中逐一取出弹幕数据
            NSString *comment = [self.bulletComments firstObject];
            [self.bulletComments removeObjectAtIndex:0];

            // 创建弹幕view
            [self createBulletView:comment trajectory:trajectory];
        }
    }

根据弹幕内容和弹幕轨迹创建弹幕

// 初始化XZBulletView
    XZBulletView *view = [[XZBulletView alloc] initWithComment:comment];
    view.trajectory = trajectory;
    [self.bulletViews addObject:view];

    __weak typeof(view) weakView = view;
    __weak typeof(self) weakSelf = self;
    view.moveStatusBlock = ^(MoveStatus status){
        if (self.bStopAnimation) { // 如果停止动画,直接return
            return;
        }
        switch (status) {
            case Start:
            {
                // 弹幕开始进入屏幕,将view加入到弹幕管理的变量中bulletViews
                [weakSelf.bulletViews addObject:weakView];
                break;
            }
            case Enter:
            {
                // 弹幕完全进入屏幕,判断是否还有其他内容,如果有则在该弹幕轨迹中创建一个弹幕
                NSString *commentNext = [weakSelf nextComment];
                if (commentNext) { // 创建新的弹幕
                    [weakSelf createBulletView:commentNext trajectory:trajectory];
                }
                 break;
            }
            case End:
            {
                // 弹幕完全飞出屏幕后,从bulletViews中删除,释放资源
                if ([weakSelf.bulletViews containsObject:weakView]) {
                    [weakView stopAnimation];
                    [weakSelf.bulletViews removeObject:weakView];
                }
                // 循环
                if (weakSelf.bulletViews.count == 0) {
                    // 说明屏幕上已经没有弹幕,开始循环滚动
                    weakSelf.bStopAnimation = YES;
                    [weakSelf start];
                }
                break;
            }
            default:
                break;
        }

//        // 移出屏幕后销毁弹幕并释放资源
//        [weakView stopAnimation];
//        [weakSelf.bulletViews removeObject:weakView];
    };

    // 回调到controller
    if (self.generateViewBlock) {
        self.generateViewBlock(view);
    }

开始弹幕,并在动画完成后,释放掉自己

// 根据弹幕长度执行动画效果
    // 根据 v = s/t,时间相同情况下,距离越长,速度就越快;
    CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
    CGFloat duration = 4.0f;
    CGFloat wholeWidth = screenWidth + CGRectGetWidth(self.bounds);

    // 弹幕开始
    if (self.moveStatusBlock) {
        self.moveStatusBlock(Start);
    }

    // t = s / v;
    CGFloat speed = wholeWidth / duration;
    CGFloat enterDurartion = CGRectGetWidth(self.bounds) / speed;

    // 弹幕的自动追加
    [self performSelector:@selector(enterScreen) withObject:nil afterDelay:enterDurartion + 2];
    // 因为要改变frame的值,所以要加__block
    __block CGRect frame = self.frame;
    [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
        // 改变x坐标
        frame.origin.x -= wholeWidth;
        self.frame = frame;
    } completion:^(BOOL finished) {
        // 动画完成后,释放掉自己
        [self removeFromSuperview];
        // 回调:知道什么时候释放
        if (self.moveStatusBlock) {
            self.moveStatusBlock(End);
        }
    }];

下面附上实现的demo

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值