自定义歌词视图
效果圖
接口數據
{"showapi_res_code": 0,"showapi_res_error": "","showapi_res_body": {"ret_code": 0,"lyric": "[ti:偏愛] [ar:張蕓京] [al:仙劍奇俠傳3 電視原聲帶] [by:] [offset:0] [00:00.05]偏愛 - 張蕓京 [00:01.22]詞:葛大為 [00:02.22]曲:陳偉 [00:02.90] [00:15.80]把昨天都作廢現在你在我眼前 [00:23.03]我想愛請給我機會 [00:27.09] [00:29.57]如果我錯了也承擔 [00:32.89] [00:33.40]認定你就是答案 [00:37.07] [00:38.16]我不怕誰嘲笑我極端 [00:41.70] [00:43.26]相信自己的直覺 [00:47.19]頑固的人不喊累 [00:50.58]愛上你我不撤退 [00:56.10]我說過我不閃躲我非要這么做 [01:02.03]講不聽也偏要愛 [01:04.48]更努力愛讓你明白 [01:09.01] [01:09.78]沒有別條路能走 [01:12.92]你決定要不要陪我 [01:15.89]講不聽偏愛看我感覺愛 [01:19.25]等你的依賴對你偏愛 [01:28.90] [01:29.56]痛也很愉快 [01:35.58] [01:38.06]把昨天都作廢現在你在我眼前 [01:45.23]我想愛請給我機會 [01:49.32] [01:51.79]如果我錯了也承擔 [01:55.12] [01:55.69]認定你就是答案 [01:59.28] [02:00.40]我不怕誰嘲笑我極端 [02:04.06] [02:05.49]相信自己的直覺 [02:09.41]頑固的人不喊累 [02:12.29] [02:12.80]愛上你我不撤退 [02:18.35]我說過我不閃躲我非要這么做 [02:24.44]講不聽也偏要愛 [02:26.79]更努力愛讓你明白 [02:32.10]沒有別條路能走 [02:35.18]你決定要不要陪我 [02:38.16]講不聽偏愛看我感覺愛 [02:41.55]等你的依賴 [02:44.59]不后悔有把握 [02:47.41]我不閃躲我非要這么做 [02:51.89]講不聽也偏要愛 [02:54.17]更努力愛讓你明白 [02:58.31] [02:59.49]沒有別條路能走 [03:02.61]你決定要不要陪我 [03:05.57]講不聽偏愛看我感覺愛 [03:08.99]等你的依賴對你偏愛 [03:18.66] [03:19.26]痛也很愉快","lyric_txt": " 偏愛 張蕓京 詞:葛大為 曲:陳偉 把昨天都作廢現在你在我眼前 我想愛請給我機會 如果我錯了也承擔 認定你就是答案 我不怕誰嘲笑我極端 相信自己的直覺 頑固的人不喊累 愛上你我不撤退 我說過我不閃躲我非要這么做 講不聽也偏要愛 更努力愛讓你明白 沒有別條路能走 你決定要不要陪我 講不聽偏愛看我感覺愛 等你的依賴對你偏愛 痛也很愉快 把昨天都作廢現在你在我眼前 我想愛請給我機會 如果我錯了也承擔 認定你就是答案 我不怕誰嘲笑我極端 相信自己的直覺 頑固的人不喊累 愛上你我不撤退 我說過我不閃躲我非要這么做 講不聽也偏要愛 更努力愛讓你明白 沒有別條路能走 你決定要不要陪我 講不聽偏愛看我感覺愛 等你的依賴 不后悔有把握 我不閃躲我非要這么做 講不聽也偏要愛 更努力愛讓你明白 沒有別條路能走 你決定要不要陪我 講不聽偏愛看我感覺愛 等你的依賴對你偏愛 痛也很愉快"} }分析
從接口中可以看出歌詞的顯示時間,例如:[00:47.19]頑固的人不喊累 中00代表分,47代表秒,19代表毫秒,歌詞的界面可以用TableView顯示,根據時間滑動TableView達到效果,每一行歌詞的顏色的改變可以通過自定義Label重現drawRect方法實現,改變時間長度為下一句歌詞和這一句歌詞的時間差.
寫自定義歌詞視圖
1.自定難以歌詞model
SongwordModel.h
//歌詞 @property (nonatomic,copy)NSString * text; //歌詞顯示時間 @property (nonatomic,assign)float time;2.歌詞幫助類
Tools.h
//切割歌詞,獲取歌詞模型數組 +(NSArray *)ToolWithSongword:(NSString *)songword;Tools.m
+(NSArray *)ToolWithSongword:(NSString *)songword {// 1.切割字符串NSArray *lrcLines = [songword componentsSeparatedByString:@" "];// 2.遍歷數組,轉換成歌詞模型NSMutableArray *arr = [NSMutableArray array];for (NSString *lrcLineString in lrcLines) {// 3.跳過前幾行if ([lrcLineString hasPrefix:@"[ti"] || [lrcLineString hasPrefix:@"[ar"] || [lrcLineString hasPrefix:@"[al"] || [lrcLineString hasPrefix:@"[by"] || [lrcLineString hasPrefix:@"[offset"] || ![lrcLineString hasPrefix:@"["]) {continue;}SongwordModel *model = [Tools lyricWithString:lrcLineString];[arr addObject:model];}return arr; } //歌詞轉模型 +(SongwordModel *)lyricWithString:(NSString *)string {SongwordModel * model = [[SongwordModel alloc] init];NSString *lyr = [string substringFromIndex:18];model.text = lyr;NSString * min = [string substringWithRange:NSMakeRange(1, 2)];NSString * second = [string substringWithRange:NSMakeRange(8, 2)];NSString * microsecond = [string substringWithRange:NSMakeRange(15, 2)];model.time = [min floatValue]*60 + [second floatValue] + [microsecond floatValue]*0.01f;return model; }3.自定義歌詞Label
SongwordLabel.h
//歌詞進度 @property (nonatomic,assign)CGFloat progress;SongwordLabel.m
//重寫set方法,重新繪制 -(void)setProgress:(CGFloat)progress {_progress = progress;//重新繪制[self setNeedsDisplay]; }-(void)drawRect:(CGRect)rect {[super drawRect:rect];//1.獲取區域CGRect fillRect = CGRectMake(0, 0, self.bounds.size.width*self.progress, self.bounds.size.height);//2.選擇顏色[[UIColor blueColor] set];//3.添加顏色UIRectFillUsingBlendMode(fillRect, kCGBlendModeSourceIn); }4.自定義歌詞Cell
SongwordCell.h
//歌詞Label @property (nonatomic,strong)SongwordLabel * lyrLabel;SongwordCell.m
-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {self.lyrLabel = [[SongwordLabel alloc] init];[self.contentView addSubview:self.lyrLabel];self.lyrLabel.textAlignment = NSTextAlignmentCenter;[self.lyrLabel mas_makeConstraints:^(MASConstraintMaker *make) {make.top.equalTo(self.contentView);make.height.mas_equalTo(18);make.centerX.equalTo(self.contentView);}];}return self; }5.自定義歌詞視圖
SongwordView.h
//歌詞 @property(nonatomic,copy) NSString *songword; //當前時間 @property (nonatomic,assign) NSTimeInterval currentTime;SongwordView.m
@interface SongwordView ()<UITableViewDataSource,UITableViewDelegate> //當前行 @property (nonatomic,assign)NSInteger currentLyrIndex; //歌詞數組 @property (nonatomic,strong)NSArray * lyrList; //歌詞顯示的TableView @property (nonatomic,strong)UITableView * tableView;@end ........省略........ -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {static NSString * identifier = @"identifier";SongwordCell * cell = [tableView dequeueReusableCellWithIdentifier:identifier];if (!cell) {cell = [[SongwordCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];}if (self.lyrList) {SongwordModel * model = self.lyrList[indexPath.row];cell.lyrLabel.text = model.text;cell.lyrLabel.font = [UIFont systemFontOfSize:17];if (indexPath.row != self.currentLyrIndex) {//不是當前行,變回原來顏色cell.lyrLabel.progress = 0;}}return cell; } #pragma mark - Setter -(void)setSongword:(NSString *)songword {self.currentLyrIndex = 0;self.lyrList = [Tools ToolWithSongword:songword];[self.tableView reloadData]; } //根據當前時間刷新tableview -(void)setCurrentTime:(NSTimeInterval)currentTime {_currentTime = currentTime;//遍歷歌詞,找到對應時間應該顯示的歌詞模型for (int i=0; i<self.lyrList.count; i++) {//當前歌詞SongwordModel * model = self.lyrList[i];NSInteger next = i+1;//下一句歌詞SongwordModel * nextModel;if (next < self.lyrList.count) {nextModel = self.lyrList[next];}//判斷如果是不是當前行if (self.currentLyrIndex != i && currentTime >= model.time && currentTime<nextModel.time) {NSIndexPath * indexPath = [NSIndexPath indexPathForRow:i inSection:0];//記錄當前行self.currentLyrIndex = i;//tableview滾動到中間[self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];//刷新[self.tableView reloadData];}if (self.currentLyrIndex == i) {//獲取當前的cellNSIndexPath * currentIndexPath = [NSIndexPath indexPathForRow:i inSection:0];SongwordCell * cell = [self.tableView cellForRowAtIndexPath:currentIndexPath];//當前這句歌詞總時間CGFloat totalTime = nextModel.time - model.time;//當前這句歌詞已經走過了多長時間CGFloat progressTime = currentTime - model.time;//改變歌詞顏色cell.lyrLabel.progress = progressTime/totalTime;}} }6.音樂播放界面
PlayController.m
@interface PlayController () //播放器對象 @property (nonatomic,strong) AVPlayer *player; //歌詞視圖 @property (nonatomic,strong) SongwordView * songwordView; //歌詞定時器 @property (nonatomic,strong) CADisplayLink * lyrTimer;@end@implementation PlayController #pragma mark - Life Cycle - (void)viewDidLoad {//初始化歌詞視圖......省略......//添加定時器[self addLyrTimer];}-(void)dealloc {[self removeLyrTimer]; }#pragma mark - Event -(void)lyrChange {self.songwordView.currentTime = CMTimeGetSeconds(self.player.currentTime); }#pragma mark - Help -(void)addLyrTimer {self.lyrTimer = [CADisplayLink displayLinkWithTarget:self selector:@selector(lyrChange)];[self.lyrTimer addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; } -(void)removeLyrTimer {[self.lyrTimer invalidate];self.lyrTimer = nil; }總結
- 上一篇: Bootstrap第一章初识
- 下一篇: 超简单的visio安装教程——史上最简单