歌词处理-显示歌词 - (Obj-C)

上一篇文章讲到歌词处理(时间、歌词的截取),接下来将歌词显示到视图

实现的大概流程:
歌词与进度条上显示的时间一样,需要实时的去更新,所以
1.封装一个更新歌词的方法,在定时器方法中实时调用
2.声明一个全局的属性,用来记录当前歌词的索引,通过索引取出当前句歌词赋值

// 更新歌词
- (void)updateLyric{
    
    // 当前歌词
    JSLyricModel *currentLyric = self.lyricModelArray[self.currentLyricIndex];
    
    // 下一句歌词  ( 2.判断越界问题)
    JSLyricModel *nextLyric = nil;
    if (self.currentLyricIndex == self.lyricModelArray.count - 1) {
        
        // 创建一个最大的下一句歌词
        nextLyric = [[JSLyricModel alloc]init];
        // 给自定义出来的最后一条歌词设置数据  (设置成最后一条歌词的数据)
        nextLyric.content = currentLyric.content;
        // 因为当前索引已经是最后一条歌词,所以上面的歌词赋值就相当于nextLyric.content = [self.lyricModelArray lastObject].content;
        // 直接设置成歌曲的总时长
        nextLyric.initialTime = [JSMusciManager sharedMusicManager].duration;
        
    }else{
        
        nextLyric = self.lyricModelArray[self.currentLyricIndex + 1];
    }
    
    // 正向调整进度(判断越界问题): 判断时间,改变当前的歌词的索引  : 当前播放时间 > 下一句歌词的起始时间 歌词索引 +1
    if ([JSMusciManager sharedMusicManager].currentTime > nextLyric.initialTime && self.currentLyricIndex < self.lyricModelArray.count - 1) {
        
        self.currentLyricIndex++;
        
        //  拖拽进度条时,只需要显示最近当前歌词,防止拖动歌词逐条跳动
        [self updateLyric];
        // 1. 当累加到正确的当前歌词索引时,下面才给歌词赋值,否则递归调用返回
        return;
        // 如果不进行递归调用直接return: 这里更新数据的定时器间隔时间为0.1s,假如将进度条拖拽到歌词索引60的位置,那么等到定时器自动调用到到歌词索引为60的歌词数据时,需要6s的时间才可以
        
    }
    
    // 反向调整进度(判断越界问题): 当前时间 < 当前句歌词的初始时间 歌词索引-1
    if ([JSMusciManager sharedMusicManager].currentTime < currentLyric.initialTime && self.currentLyricIndex > 0) {
        
        self.currentLyricIndex--;
        [self updateLyric];
        return;
    }
    
    self.verticalLyricLabel.text = self.lyricModelArray[self.currentLyricIndex].content;
    
    
}

需要考虑的点有:

  • 调整进度条切歌:

先进行递归调用,如果自增得到的该条歌词索引不是我们调整进度条所在歌词的索引,直接return返回,不进行歌词赋值

[self updateLyric];// 调用自己
return;

如果不进行递归调用直接return: 这里更新数据的定时器间隔时间为0.1s,假如将进度条拖拽到歌词索引60的位置,那么等到定时器自动调用到到歌词索引为60的歌词数据时,需要6s的时间才可以,所以需要通过递归调用的方式,直到找到正确的歌词索引后不满足自增或自减条件了,进行歌词赋值,及时的在视图上同步歌词

  • 歌词数组越界:

上面的代码中直接使用了所以进行了判断,假设这首歌有60句歌词,已经到了第60句,再次自加就会出现越界问题,所以只有当当前歌词索引小于(数组长度-1)的时候才进行自加,同理,反向调整进度条时,只有当当前歌词索引大于零时才进行自减

当"当前歌词"索引为最后一条时,下面需要使用下一条歌词来判断,所以这里设置一条虚拟的最后一条歌词模型

    if (self.currentLyricIndex == self.lyricModelArray.count - 1) {
        // 创建一个最大的下一句歌词 (虚拟数据)
        nextLyric = [[JSLyricModel alloc]init];
        // 给自定义出来的最后一条歌词设置数据  (设置成最后一条歌词的数据)
        nextLyric.content = currentLyric.content;
        // 因为当前索引已经是最后一条歌词,所以上面的歌词赋值就相当于nextLyric.content = [self.lyricModelArray lastObject].content;
        // 直接设置成歌曲的总时长
        nextLyric.initialTime = [JSMusciManager sharedMusicManager].duration;  
    }

下面的判断处理需要一个下一条歌词:

if ([JSMusciManager sharedMusicManager].currentTime > nextLyric.initialTime && self.currentLyricIndex < self.lyricModelArray.count - 1)

这里先给最后一条虚拟的歌词模型设置了属性,从判断条件来看,暂时这里还用不到最后一条虚拟歌词的数据,后面的设置歌词根据进度变色会用到

  • 切歌后的索引越界

前面对当前播放歌曲的歌词索引进行了越界判断,不同歌曲的歌词不同,所以索引值不同,防止切歌后索引混乱甚至越界,在点击切换歌曲按钮后,要将索引清零
(上一曲、下一曲按钮点击事件中)

    // 切歌索引清零
    self.currentLyricIndex = 0;

你可能感兴趣的:(歌词处理-显示歌词 - (Obj-C))