源码

首页 » 归档 » 源码 » iOS ZHBarrage 弹幕 – CABasicAnimation动画、不卡顿弹幕动画

iOS ZHBarrage 弹幕 – CABasicAnimation动画、不卡顿弹幕动画

说明

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

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

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

弹幕展示

处理弹幕消息

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;
}
}

dome:

https://github.com/Zhangyunjiang123/ZHBarrage

作者:zhangyunjiang

链接:https://www.jianshu.com/p/95281742d7fa

(0)

本文由 投稿者 创作,文章地址:https://blog.isoyu.com/archives/ios-zhbarrage-danmu-cabasicanimationdonghuabukadundanmudonghua.html
采用知识共享署名4.0 国际许可协议进行许可。除注明转载/出处外,均为本站原创或翻译,转载前请务必署名。最后编辑时间为:12 月 21, 2018 at 12:54 上午

热评文章

发表回复

[必填]

我是人?

提交后请等待三秒以免造成未提交成功和重复