美文网首页收藏ios
iOS ZHBarrage 弹幕 - CABasicAnimat

iOS ZHBarrage 弹幕 - CABasicAnimat

作者: zhangyunjiang | 来源:发表于2018-07-13 23:59 被阅读107次

    说明

    1.大多数弹幕都采用时间来控制弹幕,能够很好的适配在播放器、或者是一些对除了弹幕动画外,其他动画很少的项目中运行。而当除了弹幕动画以外,还存在更多动画时,就会导致动画冲突,而使弹幕停留不前,内存消耗巨大。故结合实际,简单写下此弹幕

    2.此动画采用CABasicAnimation动画,与大多数动画不同采用时间来控制弹幕的走向有所不同。但是目前无法控制弹幕的停留,实际我所接触的项目也没有这个需求。

    3.存在问题点,或者说是可优化点在于创建时默认初始化多个弹幕通道,但可能程序运行中,有些通道并不能得到有效的利用,如何在利用到的时候在进行初始化,有时间我在提交一个版本。

    弹幕展示

    z9lb4-pte81.gif

    处理弹幕消息

    1.我的思路是在处理接受到弹幕到时候,从上往下依次判断所创建的通道是否畅通,若找到畅通的通道时,进行数据渲染,开始动画。当所创建的通道全部被占用时,默认将消息保存在内存中,并按时间0.2秒循环查找是否有畅通通道。当内存中没有未处理的消息时,将定时器释放,代码如下

    - (void)sendMessage:(NSMutableAttributedString *)attributedString
         withSpseed:(int)spseed
          withImage:(NSString *)imagePath
         withInsets:(UIEdgeInsets)insets {
    if (!_isaccording) {
        if (!_cacheInfoArr) {
            _cacheInfoArr = [[NSMutableArray alloc] init];
        }
        ZHModel *model = [[ZHModel alloc] init];
        model.attributedString = attributedString;
        model.imagePath = imagePath;
        model.spseed = spseed;
        model.textInsets = insets;
        [_cacheInfoArr addObject:model];
        return;
    }
    if (_cacheInfoArr && _cacheInfoArr.count > 0) {
        //别急,先处理当前缓存信息
        ZHModel *model = [[ZHModel alloc]init];
        model.attributedString = attributedString;
        model.spseed = spseed;
        model.imagePath = imagePath;
        model.textInsets = insets;
        [_cacheInfoArr addObject:model];
        return;
    }
    //是否查找到通道
    for (int i = 0; i < _countChannel; i++) {
        ZHLabel *label = [self viewWithTag:ZH_Label_tag + I];
        NSLog(@"curr channel %d unblocked = %d",i,label.unblocked);
        if (label.unblocked == YES) {
            [label updateAttributed:attributedString
                         withSpseed:spseed
                          withImage:imagePath
                         withInsets:insets];
            return;
        }
    }
    //处理未找到通道时动作
    NSLog(@"creat succeed");
    if (!_cacheInfoArr) {
        _cacheInfoArr = [[NSMutableArray alloc] init];
    }
    ZHModel *model = [[ZHModel alloc] init];
    model.attributedString = attributedString;
    model.imagePath = imagePath;
    model.spseed = spseed;
    model.textInsets = insets;
    [_cacheInfoArr addObject:model];
    if (!caCcheTime) {
        caCcheTime = [NSTimer scheduledTimerWithTimeInterval:0.2
                                                      target:self
                                                    selector:@selector(cacheTimeFunction)
                                                    userInfo:nil
                                                     repeats:YES];
    }
    }
    - (void)cacheTimeFunction{
    ZHModel *model = [_cacheInfoArr firstObject];
    for (int i = 0; i < _countChannel; i++) {
        ZHLabel *label = [self viewWithTag:ZH_Label_tag + I];
        if (label.unblocked == YES) {
            [label updateAttributed:model.attributedString
                         withSpseed:model.spseed
                          withImage:model.imagePath
                         withInsets:model.textInsets];
            [_cacheInfoArr removeObjectAtIndex:0];
            if (_cacheInfoArr.count == 0) {
                //清空集合,停止时间循环
                _cacheInfoArr = nil;
                [self stopCacheTime];
                NSLog(@"clean succeed");
            }
            return;
        }
    }
    }
    

    2.动画采用CABasicAnimation动画,并监听动画是否完成

    - (void)startAnimationandLabel:(ZHLabel *)label{
    CGFloat customLabwith = label.frame.size.width;
    int time = (ZH_ANIMATION_WIDTH + customLabwith*2 + 10)/self.spseed;
    CGFloat left_P = - (customLabwith/2 - 10);
    CGPoint center = CGPointMake(ZH_ANIMATION_WIDTH + customLabwith/2 + 5, label.center.y);
    CGPoint finishPoint = CGPointMake(left_P, label.center.y);
    CABasicAnimation *animationgo = [CABasicAnimation animationWithKeyPath:@"position"];
    animationgo.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
    animationgo.duration = time;
    animationgo.repeatCount = 1;
    animationgo.delegate = self;
    animationgo.removedOnCompletion = NO;
    animationgo.beginTime = CACurrentMediaTime();
    animationgo.fromValue = [NSValue valueWithCGPoint:center];
    animationgo.toValue = [NSValue valueWithCGPoint:finishPoint];
    [label.layer addAnimation:animationgo forKey:@"label"];
    _label = label;
    }
    #pragma mark - CAAnimationDelegate
    - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
    if (anim == [_label.layer animationForKey:@"label"]) {
        [_label.layer removeAnimationForKey:@"label"];
        _label.unblocked = YES;
    }
    }
    

    介绍

    给我们项目打一个广告吧,欢迎去AppStore搜索下载"欢乐狼人杀",有什么想法,或者看法,也可能联系我,欢迎大神点评

    wiscq-y36zs.gif

    dome:
    https://github.com/Zhangyunjiang123/ZHBarrage

    相关文章

      网友评论

        本文标题:iOS ZHBarrage 弹幕 - CABasicAnimat

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