上一篇中 简单写到了关于AVPlayer播放器中 有关单例方面的 东西 单例相对于其他 还是比较方便耐用的 接下来 开始写大致布局 以及控制器中的实现
播放列表界面就不提了 大致讲下 播放界面的 布局 在播放界面上 有一个ImageView图片 圆形状的 随着歌曲时间不断旋转 划一下 会出现一个tableView界面 会显示具体的歌词
大致上能用到的
#import <UIKit/UIKit.h>
@interface AudioPlayerView : UIView
@property (nonatomic, retain) UIImageView *audioPlayerIamge;
@property (nonatomic, retain) UITableView *geCiView;
@property (nonatomic, retain) UIScrollView *BGScrollView;
@property (nonatomic, retain) UISlider *volumeSlider;
@property (nonatomic, retain) UISlider *shiJianSlider;
@property (nonatomic, retain) UIButton *lastButton;
@property (nonatomic, retain) UIButton *stopButton;
@property (nonatomic, retain) UIButton *nextButton;
@property (nonatomic, retain) UILabel *beginLabel;
@property (nonatomic, retain) UILabel *endLabel;
@end
播放列表 注释的代码是可以替换的代码 那种方式都能实现
#import "FirstTableViewController.h"
#import "FirstTableViewCell.h"
#import "MusicListModel.h"
#import "AudioPlayerViewController.h"
@interface FirstTableViewController ()
@property (nonatomic, retain) NSMutableArray *dataArray;
@end
@implementation FirstTableViewController
- (void)viewDidLoad {
[self setUpData];
[super viewDidLoad];
self.navigationItem.title = @"音乐列表";
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)setUpData
{
[[MusicListManager shareManager] requestDataForReloadWithBlock:^(NSArray *array) {
self.dataArray = [NSMutableArray arrayWithArray:array];
[self.tableView reloadData];
}];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [[MusicListManager shareManager]getAllDataArrayCount];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 200;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *idenitifier = @"MyCell";
FirstTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:idenitifier];
if (cell == nil) {
cell = [[FirstTableViewCell alloc] initWithStyle:(UITableViewCellStyleSubtitle) reuseIdentifier:idenitifier];
}
// MusicListModel *model = [[MusicListManager shareManager] getMusicListModelAtIndex:indexPath.row];
// MusicListModel *model = self.dataArray[indexPath.row];
// [cell setModel:model];
cell.model = [[MusicListManager shareManager]getMusicListModelAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
AudioPlayerViewController *audioPlayerVC = [AudioPlayerViewController shareManager];
// MusicListModel *model = [[MusicListManager shareManager] getMusicListModelAtIndex:indexPath.row];
// audioPlayerVC.model = model;
audioPlayerVC.index = indexPath.row;
[self.navigationController pushViewController:audioPlayerVC animated:NO];
}
播放界面的代码
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
@interface AudioPlayerViewController : UIViewController<AVAudioPlayerDelegate>
@property (nonatomic, retain) MusicListModel *model;
@property (nonatomic, assign) NSInteger index;
-(NSMutableArray *) returnArray:(MusicListModel *)model;
+ (instancetype)shareManager;
@end
具体实现
#import "AudioPlayerViewController.h"
#import "AudioPlayerView.h"
#import "GeCiTableViewCell.h"
#import "MusicLyricManager.h"
@interface AudioPlayerViewController ()<UITableViewDelegate,UITableViewDataSource,MusicPlayerManagerDelegate>
{
// 设置接收进来的index 对应取出model
NSInteger correntIndex;
}
@property (nonatomic, strong) GeCiTableViewCell *cell;
@property (nonatomic, retain) NSMutableArray *musicWordArray;
@end
@implementation AudioPlayerViewController
#pragma mark - 单例初始化视图控制器
// 单例
+ (instancetype)shareManager
{
static AudioPlayerViewController *manager = nil;
static dispatch_once_t onceToken;
dispatch_once (&onceToken, ^{
manager = [[[self class] alloc] init];
});
return manager;
}
#pragma mark - 视图将要出现
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:YES];
if (correntIndex == self.index) {
[self updateUI];
return;
} else {
correntIndex = self.index;
}
[self updateUI];
}
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.title = self.model.name;
self.view.backgroundColor = [UIColor whiteColor];
// 遮盖图片四周的白色
self.edgesForExtendedLayout = UIRectEdgeNone;
// 代理
[MusicPlayerManager shareMusicPlayer].delegete = self;
[self addSubview];
}
#pragma mark - 刷新界面
- (void)updateUI
{
[[MusicPlayerManager shareMusicPlayer] playingWithUrl:self.model.mp3Url];
#pragma mark - 刷新图片
AudioPlayerView *audioView = (AudioPlayerView *)[self.view viewWithTag:100];
[audioView.audioPlayerIamge sd_setImageWithURL:[NSURL URLWithString:self.model.picUrl]];
#pragma mark - 标题名
self.navigationItem.title = self.model.name;
//#pragma mark - 刷新歌曲时间
CGFloat duration = [self.model.duration floatValue]/1000;
audioView.shiJianSlider.maximumValue = duration;
#pragma mark - 刷新歌词
[[MusicLyricManager shareManager] formatLricModelWithLyric:self.model.lyric];
[audioView.geCiView reloadData];
}
#pragma mark - 获取当前播放的model
- (MusicListModel*)model
{
MusicListModel *model = [[MusicListManager shareManager] getMusicListModelAtIndex:correntIndex];
return model;
}
#pragma mark - 布置视图
- (void)addSubview
{
AudioPlayerView *audioPlayerView = [[AudioPlayerView alloc] init];
audioPlayerView.tag = 100;
[audioPlayerView.audioPlayerIamge sd_setImageWithURL:[NSURL URLWithString:self.model.picUrl]];
audioPlayerView.geCiView.separatorStyle = UITableViewCellSeparatorStyleNone;
audioPlayerView.geCiView.delegate = self;
audioPlayerView.geCiView.dataSource = self;
#pragma mark - 两个Slider 设置点击方法
[audioPlayerView.volumeSlider addTarget:self action:@selector(voiceSliderAction:) forControlEvents:(UIControlEventValueChanged)];
[audioPlayerView.shiJianSlider addTarget:self action:@selector(playSliderAction:) forControlEvents:(UIControlEventValueChanged)];
audioPlayerView.shiJianSlider.value = 0;
#pragma mark - Button 点击事件
[audioPlayerView.lastButton addTarget:self action:@selector(actionShang:) forControlEvents:(UIControlEventTouchUpInside)];
[audioPlayerView.stopButton addTarget:self action:@selector(actionStop:) forControlEvents:(UIControlEventTouchUpInside)];
[audioPlayerView.nextButton addTarget:self action:@selector(actionNext:) forControlEvents:(UIControlEventTouchUpInside)];
self.view = audioPlayerView;
}
#pragma mark - 播放 暂停
- (void)actionStop:(UIButton *)button
{
BOOL isPlaying = [[MusicPlayerManager shareMusicPlayer] musicPlayOrPause];
if (isPlaying) {
[button setTitle:@"暂停" forState:(UIControlStateNormal)];
} else {
[button setTitle:@"开始" forState:(UIControlStateNormal)];
}
}
#pragma mark - 上一首
- (void)actionShang:(UIButton *)button
{
correntIndex--;
if (correntIndex < 0) {
correntIndex = [[MusicListManager shareManager] getAllDataArrayCount] - 1;
}
[self updateUI];
}
#pragma mark - 下一首
- (void)actionNext:(UIButton *)button
{
correntIndex++;
if (correntIndex > [[MusicListManager shareManager]getAllDataArrayCount ] - 1) {
correntIndex = 0;
}
[self updateUI];
}
#pragma make - 声音滑动条
- (void)voiceSliderAction:(UISlider *)sender
{
[MusicPlayerManager shareMusicPlayer].volum = sender.value;
}
#pragma mark - 快进快退方法
-(void)playSliderAction:(UISlider *)sender
{
NSLog(@"!!!!!!!%@",sender);
CGFloat dutation = [self.model.duration floatValue] / 1000;
if (sender.value >= dutation) {
return;
}
[[MusicPlayerManager shareMusicPlayer] musicSeekToTime:sender.value];
}
#pragma mark - 歌词界面的tableView
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[MusicLyricManager shareManager] getLyricModelCount];
}
- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *idenitifier = @"GeCiCell";
self.cell = [tableView dequeueReusableCellWithIdentifier:idenitifier];
if (self.cell == nil) {
self.cell = [[GeCiTableViewCell alloc] initWithStyle:(UITableViewCellStyleSubtitle) reuseIdentifier:idenitifier];
}
self.cell.geCiLabel.text = [NSString stringWithFormat:@"%@", [[MusicLyricManager shareManager]lyricAtIndex:indexPath.row]];
// 选中
UIView * selectedView = [[UIView alloc]init];
selectedView.backgroundColor = [UIColor clearColor];
self.cell.selectedBackgroundView = selectedView;
self.cell.highlighted = YES;
self.cell.geCiLabel.highlightedTextColor = [UIColor colorWithRed:arc4random() % 256 / 256.0 green:arc4random() % 256 / 256.0 blue:arc4random() % 256 / 256.0 alpha:1];
return self.cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 60;
}
#pragma mark - 实现代理方法
- (void)playingWithProgress:(CGFloat)progress
{
AudioPlayerView *audioView = (AudioPlayerView *)[self.view viewWithTag:100];
// 图片旋转
audioView.audioPlayerIamge.transform = CGAffineTransformRotate(audioView.audioPlayerIamge.transform, M_1_PI / 180);
// 进度条
audioView.shiJianSlider.value = progress;
// 当前播放时间
audioView.beginLabel.text = [self changeFormatWithTime:progress];
// 剩余时间
CGFloat duration = [[self.model duration] floatValue] / 1000;
audioView.endLabel.text = [self changeFormatWithTime:(duration - progress)];
// 获取当前进度对应的下标
NSInteger index = [[MusicLyricManager shareManager] indexOfTime:progress];
// 组拼 indexPath
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:0];
[audioView.geCiView selectRowAtIndexPath:indexPath animated:YES scrollPosition:(UITableViewScrollPositionMiddle)];
}
#pragma maek - 转换时间格式
- (NSString *)changeFormatWithTime:(CGFloat)time
{
// 计算分钟
int minute = time / 60;
// 计算秒
int secondes = (int) time % 60;
NSString *timeFormat = [NSString stringWithFormat:@"%02d:%02d", minute, secondes];
return timeFormat;
}
小贴士
// imageView设置成正方形 通过下面的代码 可以让他变成圆形
self.audioPlayerIamge.layer.cornerRadius = self.audioPlayerIamge.frame.size.width / 2;
self.audioPlayerIamge.layer.masksToBounds = YES;
效果图