麻雀雖小,五髒俱全.在平時的項目中,任何一個模塊或者功能裡其實都隱藏著許多我們平時注意不到的知識點,其實很多東西大家每天都在用,但很多時候都是知其然,而不知其所以然.時間久了,也就懶得去想到底是什麼原因了,怎麼實現的之類.回想自己的學習路程,也基本都這樣混過來,實在愧對光陰,近日抽空,查看過往筆記,順手寫了個小代碼練習,感覺溫故知新.現分享代碼,以供新手入門參考,尤其其中錯誤的部分也很有廣泛性.同時也歡迎各路成精的老鳥們噴吐,能夠指正,這樣也促進我再進步一點.
ViewController.m文件如下:
復制代碼
1 #import "ViewController.h"
2 #import "Word.h"
3 #import "AudioPlayTool.h"
4 #import "NSString+CJZ.h"
5
6
7 @interface ViewController ()<UIPickerViewDataSource,UIPickerViewDelegate>
8
9 @property (nonatomic,strong) NSArray *wordsArray; // 存儲對象word,word是根據歌詞文件生成的一個對象,用來在PickerView顯示一行的信息;
10 @property (nonatomic,assign) int index; // 播放索引;
11 @property (nonatomic,strong) CADisplayLink *playLink; // 定時器;
12 @property (nonatomic,strong) AudioPlayTool * playTool; // 播放類工具,用來播放歌曲,
13
14 @property (weak, nonatomic) IBOutlet UIPickerView *wordListPicker; // 顯示歌詞的PickerView
15
16
17 @end
18
19 @implementation ViewController
20 - (IBAction)nextClick {
21 [self.wordListPicker selectRow:self.index inComponent:0 animated:YES];
22 }
23
24
25 - (AudioPlayTool *)playTool
26 {
27 if (_playTool == nil) {
28 _playTool = [[AudioPlayTool alloc]init];
29 }
30 return _playTool;
31 }
32
33 - (CADisplayLink *)playLink
34 {
35 if (_playLink == nil) {
36 _playLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateInfo:)];
37 }
38 return _playLink;
39 }
40
41 - (NSArray *)wordsArray
42 {
43 if (_wordsArray == nil) {
44 _wordsArray = [NSArray array];
45 }
46 return _wordsArray;
47 }
48
49 - (void)viewDidLoad
50 {
51 [super viewDidLoad];
52 NSString *path = [[NSBundle mainBundle]pathForResource:@"Set Fire To The Rain_歌詞.lrc" ofType:nil];
53 self.wordsArray = [[Word alloc] wordsWithFilePath:path];
54 [self.playTool prepareAudioWithName:@"31071114.mp3"];
55 [self.playTool play];
56 [self.playLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
57
58 }
59
60 #pragma mark - UIPickerView DataSource and Delegate;
61
62 - (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component
63 {
64 return 40;
65 }
66
67 - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
68 {
69 return 1;
70 }
71 - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
72 {
73 return self.wordsArray.count;
74
75 }
76
77
78 - (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
79 {
80 UILabel *textLable = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 320, 40)];
81 Word *textWord = self.wordsArray[row];
82 textLable.text = textWord.text;
83 textLable.font = [UIFont systemFontOfSize:13];
84 textLable.numberOfLines = 0;
85 return textLable;
86 }
87 - (void)updateInfo:(CADisplayLink *)display
88 {
89 AVAudioPlayer *player = self.playTool.audioPlay;
90 double currentTime = player.currentTime;
91 NSString *change2Time = [NSString getMinuteSecondWithSecond:currentTime];
92 double compareTime = [NSString getTimeWithString:change2Time];
93
94 for (int i = 0; i < self.wordsArray.count; i++)
95 {
96 Word *beginW = self.wordsArray[i];
97 double wordTime = [NSString getTimeWithString:beginW.time];
98 Word *nextW = nil;
99 int next = i + 1;
100 if (next < self.wordsArray.count) {
101 nextW = self.wordsArray[next];
102 if (compareTime >= wordTime && compareTime <= [NSString getTimeWithString:nextW.time])
103 {
104 dispatch_async(dispatch_get_main_queue(), ^{
105 self.index = i + 1;
106 [self nextClick];
107 });
108 break;
109 }
110 }
111 }
112 }
113
114
115
116 @end
復制代碼
其中,加載歌詞的文件是通過封裝的Word類進行裝換:
word.h
復制代碼
1 #import <Foundation/Foundation.h>
2
3 @interface Word : NSObject
4 @property (nonatomic,copy)NSString *time;
5 @property (nonatomic,copy)NSString *text;
6
7 + (instancetype)wordWithString:(NSString *)string; //工具方法,根據特定的字符串,生成word對象;
8 - (instancetype)initWithString:(NSString *)string; // 同上;
9
10 - (NSArray *)wordsWithFilePath:(NSString *)path; // 根據文件路徑,生成包含多個word對象的數組;
11
12 @end
復制代碼
word.m
復制代碼
1 #import "Word.h"
2
3 @implementation Word
4
5 - (instancetype)initWithString:(NSString *)string
6 {
7 if (self = [super init]) {
8 NSRange rangeOne = NSMakeRange(1, 5);
9 self.time = [string substringWithRange:rangeOne];
10 self.text = [string substringFromIndex:10];
11 }
12 return self;
13 }
14
15 + (instancetype)wordWithString:(NSString *)string
16 {
17 return [[self alloc]initWithString:string];
18 }
19
20 - (NSArray *)wordsWithFilePath:(NSString *)path
21 {
22 NSError *error = nil;
23 NSString *original = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error];
24 NSArray *stringArray = [original componentsSeparatedByString:@"\n"];
25 NSMutableArray *lastArray = [NSMutableArray array];
26 for (NSString *string in stringArray) {
27 if ((string.length > @"[00:00:00]".length ) && [string hasPrefix:@"[0"]) {
28 [lastArray addObject:string];
29 }
30 }
31 NSMutableArray *wordsArray = [NSMutableArray array];
32 for (NSString *string in lastArray) {
33 Word *singleWord = [Word wordWithString:string];
34 [wordsArray addObject:singleWord];
35 }
36 return [wordsArray copy];
37 }
38 @end
復制代碼
其中,播放音樂的工具類如下:
AVAudioPlayer.h
復制代碼
1 #import <Foundation/Foundation.h>
2 #import <AVFoundation/AVFoundation.h>
3
4 @class AVAudioPlayer ;
5 @interface AudioPlayTool : NSObject
6
7 @property (nonatomic,strong,readonly ) AVAudioPlayer *audioPlay;
8
9 - (void)prepareAudioWithName:(NSString *)name;
10 - (void)play;
11 - (void)stop;
12 - (void)pause;
13
14 @end
復制代碼
AVAudioPlayer.m
復制代碼
1 #import "AudioPlayTool.h"
2
3
4 @interface AudioPlayTool()
5
6
7 @end
8
9 @implementation AudioPlayTool
10
11
12 - (void)prepareAudioWithName:(NSString *)name
13 {
14 NSError *error = nil;
15 NSString *songPath = [[NSBundle mainBundle] pathForResource:name ofType:nil];
16 AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:songPath] error:&error];
17 if (error) {
18 return;
19 }
20 [player prepareToPlay];
21 _audioPlay = player;
22 }
23
24 - (void)play
25 {
26 if (![_audioPlay isPlaying]) {
27 [self.audioPlay play];
28
29 }
30 }
31
32 - (void)stop
33 {
34 [self.audioPlay stop];
35 }
36
37 - (void)pause
38 {
39 if ([_audioPlay isPlaying]) {
40 [self.audioPlay pause];
41
42 }
43 }
44
45 @end
復制代碼
自己寫的一個字符串分類,
復制代碼
#import <Foundation/Foundation.h>
@interface NSString (CJZ)
/**
* 返回分與秒的字符串 如:01:60
*/
+(NSString *)getMinuteSecondWithSecond:(NSTimeInterval)time;
+(NSTimeInterval) getTimeWithString:(NSString *)string;
@end
復制代碼
.m部分:
復制代碼
#import "NSString+CJZ.h"
@implementation NSString (CJZ)
+(NSString *)getMinuteSecondWithSecond:(NSTimeInterval)time{
int minute = (int)time / 60;
int second = (int)time % 60;
if (second > 9) {
return [NSString stringWithFormat:@"%d:%d",minute,second];
}
return [NSString stringWithFormat:@"%d:0%d",minute,second];
}
+ (NSTimeInterval)getTimeWithString:(NSString *)string{
if (string.length == 5) {
double first = [[string substringWithRange:NSMakeRange(1, 1)] doubleValue];
double second = [[string substringFromIndex:3] doubleValue];
return first + second * 0.01;
}
double first = [[string substringWithRange:NSMakeRange(0, 1)] doubleValue];
double second = [[string substringFromIndex:2] doubleValue];
return first + second * 0.01;
}
@end