一.歌词的展示 -- 首先歌词是在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
- 外部进度值的计算