[實現跑馬燈,以及彈幕] -- iOS

HBPmd

設計圖.jpg
設計圖.jpg

用法

{

    HBdansView *_randomDansView;
  
}

    _randomDansView = [[HBdansView alloc] initWithFrame:CGRectMake(0, 84, self.view.width, 320)]; //初始化
 
    [self.view addSubview:_randomDansView];

    [_randomDansView addRandomText:@"需要展現的文字"];

需求

  • 上圖中有兩種方式去展示彈幕
  • 廣播式:每次只播放一條數據。
  • 分布式:屏幕中最多顯示3條數據

實在想不出其他名字,暫用分布式來表述吧。

思路

分兩部分

  • 背景
  • 文字

實現

首先的話,文字是用一個UILable添加到背景UIView上面。但是分布式怎么辦?由此設計一個對外屬性countInScreen來確定,同時可以在屏幕顯示多少個彈幕的內容。

- (void)setCountInScreen:(NSInteger)countInScreen
{
    _countInScreen = countInScreen;
    
    if (self.randomSet.count) [self.randomSet removeAllObjects];
    //    隨機
    if (_countInScreen > 10) _countInScreen = 10;
    CGFloat margin = (self.height - _countInScreen * defaultH) / (_countInScreen + 1);
    for (NSInteger i = 0; i < _countInScreen; i++) {
        HBdansLable *randomLable = [HBdansLable dansLableFrame:[self randomFrame]];
        randomLable.y = i * (margin + defaultH) + margin;
        randomLable.delegate = self;
        randomLable.layer.masksToBounds = YES;
        
        [self.randomSet addObject:randomLable];
        
    }
    
}

在代碼中,會創建等數目HBdansLable自定義Lable,算出自己的frame。當然,間距是等分的。

randomSet是一個可變的集合。是這樣的

- (NSMutableSet *)randomSet
{
    if (!_randomSet) {
        
        _randomSet = [NSMutableSet set];
        
    }
    return _randomSet;
}

搞這個集合的目的是:一開始所有新創建的對象都放這里面去,你可以把這個想象成一個緩存池。用的時候從里面取出HBdansLable對象,展示出來;彈幕滾出父試圖,就把此對象回收,重新加到randomSet集合中。

這樣你所需的所有HBdansLable對象,在一開始的時候就已經創建好了。后面用的時候,不需要重復創建。

#pragma mark - HBdansLableDelegate
- (void)dansLable:(HBdansLable *)dansLable isOutScreen:(BOOL)isOutScreen
{
   if (isOutScreen) {
       
       dansLable.x = CGRectGetMaxX(self.frame);//更新x值
       
       [dansLable removeFromSuperview];//從父試圖中移除
       
       [self.randomSet addObject:dansLable];//添加到集合中國
       
       if (self.randomMutableArray.count){
           
           [self dequeRandomLable:[self.randomMutableArray firstObject]];
           [self.randomMutableArray removeObjectAtIndex:0];
           
       }
   }
}

完成回收HBdansLableDelegate通知;

每個HBdansLable都需要自己去移動,更新frame

- (void)setText:(NSString *)text
{
   [super setText:text];
   //1.更具文字內容算出寬高
   CGRect contextFrame = [text boundingRectWithSize:CGSizeMake(MAXFLOAT, self.height)
                                            options:NSStringDrawingUsesLineFragmentOrigin
                                         attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:17]}
                                            context:nil];
   NSString *str = [NSString stringWithFormat:@"%.f",contextFrame.size.width + 10];
   self.width = [str floatValue];
   self.height = contextFrame.size.height + 6;
   //2.開始彈幕
   [self starDans];
}

重寫HBdansLable setter方法,啟動彈幕;

- (void)starDans
{
   
   self.displayLink.paused = NO;
   [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
   self.isStar = YES;
   
}
- (void)stopDans
{
   if (self.displayLink.isPaused) return;
   self.displayLink.paused = YES;
   self.isStar = NO;
   [self.displayLink invalidate];
   self.displayLink = nil;
   
}

一定要加入RunLoop循環中,否則觸摸屏幕或者他操作會影響彈幕不再移動。銷毀神馬的,你們都懂的。

結束總結

就兩個注意

  • HBdansLable自己控制移動,算出寬高
  • 父試圖控制回收HBdansLable(不需要重復創建);

如果這個文章幫到了你,一定給我Star哦!

GitHub 歡迎圍觀!!

Tip

  • 本項目僅支持文字彈幕,后續會持續更新。
  • 實現思路僅來源項目需求,所以不是完全適用所有需求場景。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,353評論 25 708
  • *面試心聲:其實這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個offer,總結起來就是把...
    Dove_iOS閱讀 27,211評論 30 472
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,766評論 18 399
  • 1、 瞧一滴淚的轟炸 顫栗了亞歐大陸的胴體 心痛來勢兇猛 只瞬間極速向高地挺進 瞧大地蒼白的靈魂 出賣給了魔鬼的淫...
    love垂楊紫陌閱讀 59評論 3 7
  • 還幾個小時就要到機場飛回國了。這是我第一次用手機碼簡書,力求短小精湛。 日本到中國不遠,機票也不是太貴,但,我想還...
    少女冉閱讀 283評論 1 11