HBPmd

設計圖.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
- 本項目僅支持
文字彈幕
,后續會持續更新。 - 實現思路僅來源項目需求,所以不是完全適用所有需求場景。