标签:
/** 歌曲名称 */
var name: String?
/** 歌曲文件名称 */
var filename: String?
/** 歌曲文件名称 */
var lrcname: String?
/** 演唱者 */
var singer: String?
/** 歌手头像 */
var singerIcon: String?
/** 专辑图片 */
var icon: String?
//重写了下面的方法,此方法是必须重写的
override init() {
super.init()
}
/** KVC */
init(dict : [String : AnyObject]) {
super.init()
setValuesForKeysWithDictionary(dict)
}
//异常处理
override func setValue(value: AnyObject?, forUndefinedKey key: String) {
}
class XFJQQMusicDataTool: NSObject {
//** 设计一个方法,用来返回数据模型 */
class func getMusicList( result: (musicMs : [XFJQQMusicModel]) ->()) {
//加载本地的plist文件
guard let path = NSBundle.mainBundle().pathForResource("Musics.plist", ofType: nil) else {
result(musicMs: [XFJQQMusicModel]())
return
}
//加载文件的内容
guard let dictArray = NSArray(contentsOfFile: path) else {
result(musicMs: [XFJQQMusicModel]())
return
}
//把字典转成模型
var resultMs = [XFJQQMusicModel]()
//遍历
for dict in dictArray {
let musicM = XFJQQMusicModel(dict: dict as! [String : AnyObject])
resultMs.append(musicM)
}
//以闭包的形式返回出去
result(musicMs: resultMs)
}
}
extension XFJQQListTVC {
//初始化设置
func setUpInit() {
setUpTableView()
setUpNavigationBar()
}
//通过一个方法来设置tableView的相关设置
private func setUpTableView() {
//tableView的背景图片
let backView = UIImageView(image: UIImage(named: "QQListBack"))
tableView.backgroundView = backView
//cell的高度
tableView.rowHeight = 60
//分割线
tableView.separatorStyle = .None
}
//设置导航条隐藏
private func setUpNavigationBar() {
navigationController?.navigationBarHidden = true
}
//设置状态栏的样式
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return .LightContent
}
}
override func viewDidLoad() {
super.viewDidLoad()
XFJQQMusicDataTool.getMusicList { (musicMs) -> () in
//将返回的数组装入模型中
self.musicMs = musicMs
}
setUpInit()
}
//只要有数据变化,就刷新表格
var musicMs : [XFJQQMusicModel] = [XFJQQMusicModel]() {
didSet {
tableView.reloadData()
}
}
//** 歌手的头像 */
@IBOutlet weak var iconImageView: UIImageView!
//** 歌名 */
@IBOutlet weak var songName: UILabel!
//** 演唱者 */
@IBOutlet weak var singerName: UILabel!
//重写模型的set方法,用模型给xib的属性赋值
var musicM : XFJQQMusicModel? {
didSet {
//容错处理
if musicM?.icon != nil {
iconImageView.image = UIImage(named:musicM!.icon!)
}
songName.text = musicM?.name
singerName.text = musicM?.singer
}
}
//当加载xib的时候一定会调用
override func awakeFromNib() {
super.awakeFromNib()
//处理头像
iconImageView.layer.cornerRadius = iconImageView.width * 0.5
iconImageView.layer.masksToBounds = true
}
//提供一个方法,返回由xib创建的cell
class func cellWithTableView(tableView : UITableView) ->XFJQQMusicListCell {
let cellID = "cellID"
var cell = tableView.dequeueReusableCellWithIdentifier(cellID) as? XFJQQMusicListCell
if cell == nil {
//检查是否有循环利用
print("创建cell")
cell = NSBundle.mainBundle().loadNibNamed("XFJQQMusicListCell", owner: nil, options: nil).first as? XFJQQMusicListCell
}
return cell!
}
//重写cell的hightlight方法,一遍点击cell的时候cell不在高亮
override func setHighlighted(highlighted: Bool, animated: Bool) {
}
//动画的样式
enum AnimationType {
case Rotation
case Translation
}
///MARK : - 动画(核心动画)
extension XFJQQMusicListCell {
func beginAnimation(type : AnimationType) {
//用switch做判断(执行哪种动画)
switch type {
case .Rotation:
//移除上一个动画
self.layer.removeAnimationForKey("rotation")
//做怎样的动画
let animation = CAKeyframeAnimation(keyPath: "transform.rotation.z")
//动画之间的角度
animation.values = [M_PI * 0.25, 0]
//动画时长
animation.duration = 0.2
//添加动画
self.layer.addAnimation(animation, forKey: "rotation")
case .Translation:
self.layer.removeAnimationForKey("translation")
let animation = CAKeyframeAnimation(keyPath: "transform.translation.x")
animation.values = [60, 0]
animation.duration = 0.3
self.layer.addAnimation(animation, forKey: "translation")
}
}
}
//** 行 */
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return musicMs.count
}
//** cell显示的内容 */
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
//通过方法获得cell
let cell = XFJQQMusicListCell.cellWithTableView(tableView)
//取出模型
let musicM = musicMs[indexPath.row]
//赋值(cell.musicM: 模型的set方法,通过该方法来赋值)
cell.musicM = musicM
//返回cell
return cell
}
//开始做动画
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
//将系统的cell转为xib的cell
let cell = cell as! XFJQQMusicListCell
//开始动画
cell.beginAnimation(AnimationType.Translation)
}
class XFJQQMusicTool: NSObject {
//创建播放器
var avplayer : AVAudioPlayer?
//设置一个方法,又外界直接传入一个文件名,然后就直接播放
func getplayMusic(name : String) ->(){
//获取传入的文件url(并且判断)
guard let url = NSBundle.mainBundle().URLForResource(name, withExtension: nil) else {return}
//由url来判断播放的是否是同一首歌
if url == avplayer?.url {
//播放的是同一首歌
avplayer?.play()
return
}
//播放传入的url的歌曲
do {
avplayer = try AVAudioPlayer(contentsOfURL: url)
}catch{
//打印错误信息
print(error)
return
}
//准备播放
avplayer?.prepareToPlay()
//开始播放
avplayer?.play()
}
//** 重新播放 */
func resumeCurrentMusic() ->() {
avplayer?.play()
}
//** 暂停播放 */
func pauseCurrentMusic() ->() {
avplayer?.pause()
}
//设置单例
static let shareInstance = XFJQQMusicOperationTool()
//设置一个属性记录正在播放的音乐的角标(并且提供set方法)
var index = 0 {
didSet {
if index < 0
{
index = (musicList?.count ?? 0) - 1
}
if index > (musicList?.count ?? 0) - 1
{
index = 0
}
}
}
//** 上一首 */
func preMusic() ->() {
index -= 1
//判断
if let tempList = musicList {
//取出模型
let musicM = tempList[index]
//根据模型播放音乐
getplayMusic(musicM)
}
}
//** 下一首 */
func nextMusic() ->() {
index += 1
//判断
if let tempList = musicList {
//取出模型
let musicM = tempList[index]
//根据模型播放音乐
getplayMusic(musicM)
}
}
//创建模型的音乐播放列表
var musicList : [XFJQQMusicModel]?
//创建操作音乐的对象
let tool = XFJQQMusicTool()
//提供一个方法由外界通过这个方法播放音乐
func getplayMusic(musicM : XFJQQMusicModel) ->() {
//通过传入的模型,拿到模型中歌名属性(filename)
let fileName = musicM.filename ?? ""
//完成对歌曲的播放
tool.getplayMusic(fileName)
//容错处理(如果没有歌曲,就直接退出)
if musicList == nil {
return
}
//记录下当前在播放的音乐的索引
index = (musicList?.indexOf(musicM))!
}
//** 播放 */
func playCurrentMusic() ->() {
tool.resumeCurrentMusic()
}
//** 暂停 */
func pauseCurrentMusic() ->() {
tool.pauseCurrentMusic()
}
//用户点击了某行cell,播放对应的歌曲
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
//取出行模型
let musicM = musicMs[indexPath.row]
//播放
XFJQQMusicOperationTool.shareInstance.getplayMusic(musicM)
//通过绑定的suge,当点击某行cell的时候,跳转到下一个界面
performSegueWithIdentifier("listToDetail", sender: nil)
}
///MARK : - 只负责属性
class XFJQQDetailVC: UIViewController {
//** 歌手头像 */
@IBOutlet weak var foreImageView: UIImageView!
//** 歌词能显示的并且滚动的View */
@IBOutlet weak var lrcBackView: UIScrollView!
//** 进度 */
@IBOutlet weak var progressSlider: UISlider!
//** 歌名 */
@IBOutlet weak var lrcLabel: UILabel!
//** 展示歌词的view */
var lrcview : UIView?
}
//** 下一首音乐 */
@IBAction func nextButton()
{
XFJQQMusicOperationTool.shareInstance.nextMusic()
}
//** 上一首音乐 */
@IBAction func previous()
{
XFJQQMusicOperationTool.shareInstance.preMusic()
}
//** 播放和暂停 */
@IBAction func playAndPause(button : UIButton)
{
button.selected = !button.selected
//判断
if button.selected {
XFJQQMusicOperationTool.shareInstance.pauseCurrentMusic()
}else {
XFJQQMusicOperationTool.shareInstance.playCurrentMusic()
}
}
//** 设置方法用来添加调用一次性的设置 */
private func setUpOnce() ->() {
addLrcView()
setProgressSlider()
}
//** 设置方法用来添加调用多次的设置 */
private func setUpLrcFrame() ->() {
setUpLrcViewFrame()
setUpForeImage()
}
//** 设置进度条的背景图片 */
private func setProgressSlider() ->() {
progressSlider.setThumbImage(UIImage(named: "player_slider_playback_thumb"), forState: UIControlState.Normal)
}
//** 计算显示歌词的view的frame */
private func setUpLrcViewFrame() {
//lrcview的frame值
lrcview?.frame = lrcBackView.bounds
//lrcview的x值
lrcview?.x = lrcBackView.width
//设置拖动显示歌词的view的contensize
lrcBackView.contentSize = CGSizeMake(lrcBackView.width * 2.0, 0)
}
//** 负责添加控件(只需要添加一次即可) */
private func addLrcView() ->() {
//创建显示歌词的view
lrcview = UIView()
//设置背景颜色
lrcview?.backgroundColor = UIColor.redColor()
//添加到滚动的view中
lrcBackView.addSubview(lrcview!)
//开启分页模式
lrcBackView.pagingEnabled = true
//隐藏水平滚动条
lrcBackView.showsHorizontalScrollIndicator = false
//设置scorllView的代理
lrcBackView.delegate = self
}
//** 设置圆角图片 */
private func setUpForeImage() ->() {
foreImageView.layer.cornerRadius = foreImageView.width * 0.5
foreImageView.layer.masksToBounds = true
}
//设置状态栏的样式
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return .LightContent
}
//这些方法只需要调用一次即可
override func viewDidLoad() {
super.viewDidLoad()
setUpOnce()
}
// 在视图加载好之后, 有可能, 里面拿到的不是真实的最终frame, 有可能是xib里面的大小
//该方法会频繁调用,但是调用越频繁,frame越准确
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
setUpLrcFrame()
}
///MARK : - scrollView的代理方法的实现
extension XFJQQDetailVC : UIScrollViewDelegate {
func scrollViewDidScroll(scrollView: UIScrollView) {
let alpha = 1 - scrollView.contentOffset.x / scrollView.width
//设置背景图片的透明度
foreImageView.alpha = alpha
//设置显示歌名的label透明度
lrcLabel.alpha = alpha
}
}
标签:
原文地址:http://blog.csdn.net/xf931456371/article/details/51440805