一.歌詞的展示 -- 首先歌詞是在scrollView上,scrollView的大小是兩個屏幕的寬度
- scrollView滾動修改透明度的代碼
- 自定義展示歌詞的view,繼承自UIScrollView,向外界提供一個歌詞文件名的屬性
/** 歌詞文件的名字 */
@property(nonatomic,copy) NSString *lrcFileName;
重寫setter,解析歌詞,通過歌詞的工具類獲得模型集合
- 歌詞工具類的實現
1 #import "ChaosLrcTool.h" 2 #import "ChaosLrc.h" 3 4 @implementation ChaosLrcTool 5 + (NSArray *)lrcToolWithLrcName:(NSString *)lrcname 6 { 7 // 1.獲取文件路徑 8 NSString *lrcPath = [[NSBundle mainBundle] pathForResource:lrcname ofType:nil]; 9 // 2.加載文件內容 10 NSString *lrcString = [NSString stringWithContentsOfFile:lrcPath encoding:NSUTF8StringEncoding error:nil]; 11 // 3.切割字符串 12 NSArray *lrcLines = [lrcString componentsSeparatedByString:@"\n"]; 13 // 4.遍歷集合,轉換成歌詞模型 14 NSMutableArray *arr = [NSMutableArray array]; 15 for (NSString *lrcLineString in lrcLines) { 16 /* 17 [ti:簡單愛] 18 [ar:周傑倫] 19 [al:范特西] 20 */ 21 // 5.跳過指定行 22 if ([lrcLineString hasPrefix:@"[ti"] || [lrcLineString hasPrefix:@"[ar"] || [lrcLineString hasPrefix:@"[al"] || ![lrcLineString hasPrefix:@"["]) { 23 continue; 24 } 25 ChaosLrc *lrc = [ChaosLrc lrcWithLrcLine:lrcLineString]; 26 [arr addObject:lrc]; 27 } 28 return arr; 29 } 30 @end
- 歌詞解析完畢后,根據歌詞模型集合來實現tableView(歌詞用tableView來顯示)的數據源方法
二.歌詞的滾動
- 歌詞的滾動由每一句的時間來決定,自定義的歌詞的view需要外界不停的提供歌曲播放的時間,自己來判斷並滾動顯示對應的歌詞.所以自定義的歌詞View需要向外界提供一個時間屬性,重寫時間屬性來實現歌詞滾動
1 #pragma mark - 歌詞滾動 2 // 重寫time的setter 3 - (void)setCurrentTime:(NSTimeInterval)currentTime 4 { 5 _currentTime = currentTime; 6 // 遍歷歌詞,找到對應時間應該顯示的歌詞模型 7 for (int i = 0; i < self.lrcList.count; i++) { 8 // 當前的歌詞 9 ChaosLrc *lrc = self.lrcList[i]; 10 NSInteger next = i + 1; 11 // 下一句歌詞 12 ChaosLrc *nextLrc; 13 if (next < self.lrcList.count) { 14 nextLrc = self.lrcList[next]; 15 } 16 if (self.currentLrcIndex != i && currentTime >= lrc.time && currentTime < nextLrc.time) { 17 18 NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0]; 19 NSIndexPath *previousIndexPath = [NSIndexPath indexPathForRow:self.currentLrcIndex inSection:0]; 20 // 記錄當前行 21 self.currentLrcIndex = i; 22 // 滿足條件,tableview滾動 23 [self.lrcView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES]; 24 // 刷新上一行,字體還原 25 [self.lrcView reloadRowsAtIndexPaths:@[previousIndexPath] withRowAnimation:UITableViewRowAnimationNone]; 26 // 刷新當前行,字體變大 27 [self.lrcView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone]; 28 } 29 // 當前歌詞的label的進度 30 if (self.currentLrcIndex == i) { 31 32 // 獲取當前的cell 33 NSIndexPath *currentIndexPath = [NSIndexPath indexPathForRow:i inSection:0]; 34 ChaosLrcCell *currentCell = [self.lrcView cellForRowAtIndexPath:currentIndexPath]; 35 CGFloat totalTime = nextLrc.time - lrc.time; // 當前歌詞總時間 36 CGFloat progressTime = currentTime - lrc.time; // 當前歌詞已經走過了多長時間 37 currentCell.lrcLabel.progress = progressTime / totalTime; 38 39 // 主頁的label 40 self.mainLabel.text = lrc.text; 41 self.mainLabel.progress = currentCell.lrcLabel.progress; 42 } 43 } 44 }
- 外界給歌詞的View提供時間就不是每一秒提供一次那么簡單了,外界需要更牛逼的定時器
- 播放的時候添加定時器
- 定時器的方法中實現給歌詞的view提供的時間屬性賦值
- 播放的時候添加定時器
三.歌詞的顏色變化 -- 畫上去的(自定義cell中的顯示歌詞的label,label需要外界提供一個進度值,自己內部根據進度值來畫)
- 自定義label的實現
1 #import "ChaosLabel.h" 2 3 @implementation ChaosLabel 4 5 - (void)setProgress:(CGFloat)progress 6 { 7 _progress = progress; 8 // 重繪 9 [self setNeedsDisplay]; 10 } 11 12 - (void)drawRect:(CGRect)rect { 13 14 [super drawRect:rect]; 15 16 // 1.獲取需要畫的區域 17 CGRect fillRect = CGRectMake(0, 0, self.bounds.size.width * self.progress, self.bounds.size.height); 18 // 2.選擇顏色 19 [[UIColor yellowColor] set]; 20 // 3.添加區域開始畫圖 21 // UIRectFill(fillRect); 22 UIRectFillUsingBlendMode(fillRect, kCGBlendModeSourceIn); 23 } 24 25 @end
-
外部進度值的計算