//一、*项目准备

1、QQ音乐App 界面素材:(我使用PP助手,将QQ音乐App备份,解压ipa文件 即可得到里面的图片素材)

2、豆瓣电台接口:"http://douban.fm/j/mine/playlist?channel=1"

//二、*界面布局
使用Xcode新建一个Single View Application项目,选择Swift语言。

导入素材图片、在默认的ViewController视图进行以下布局。

界面控件不多,如图将几个关键控件布局就可以了。

//三、*背景模糊特效
布局好就马上要写代码了,写完将会看到一个非常漂亮的效果

首先将控件关联到ViewController

 
1   @IBOutlet weak var photoBorderView: UIView!
2 @IBOutlet weak var progressSlider: UISlider!
3 @IBOutlet weak var backgroundImageView: UIImageView!
4 @IBOutlet weak var photo: UIImageView!
5 @IBOutlet weak var playButton:UIButton!
6 @IBOutlet weak var titleLabel: UILabel!
7 @IBOutlet weak var artistLabel:UILabel!
8 @IBOutlet weak var playTimeLabel:UILabel!
9 @IBOutlet weak var allTimeLabel:UILabel!
 

在viewDidLoad方法里,写上模糊特效

 
 override func viewDidLoad() {
super.viewDidLoad()
//将图像变圆形
photo.layer.cornerRadius=self.photo.frame.size.width/2.0
photo.clipsToBounds=true
photoBorderView.layer.cornerRadius=self.photoBorderView.frame.size.width/2.0
photoBorderView.clipsToBounds=true
//模糊效果
let blurEffect=UIBlurEffect(style: UIBlurEffectStyle.Dark)
let blureView=UIVisualEffectView(effect: blurEffect)
blureView.frame=self.view.frame
backgroundImageView.addSubview(blureView)
//设置slider图标
progressSlider.setMinimumTrackImage(UIImage(named: "player_slider_playback_left.png"), forState: UIControlState.Normal)
progressSlider.setMaximumTrackImage(UIImage(named: "player_slider_playback_right.png"), forState: UIControlState.Normal)
progressSlider.setThumbImage(UIImage(named: "player_slider_playback_thumb.png"), forState: UIControlState.Normal)
}
 

运行一下,看看是不是很漂亮。

//四*让图片旋转起来

先把下面这个方法写上,想看到效果就在viewDidLoad()方法里加上 rotationAnimation()进行调用。

 
 //图片旋转动画
func rotationAnimation(){
let rotation=CABasicAnimation(keyPath: "transform.rotation.z")
rotation.timingFunction=CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
rotation.toValue=2*M_PI
rotation.duration=16
rotation.repeatCount=HUGE
rotation.autoreverses=false
photo.layer.addAnimation(rotation, forKey: "rotationAnimation")
}
 

//五*弹出播放列表页

新建一个PlayListView.swift和PlayListView.xib并将xib的class关联到PlayListView

将PlayListView.xib进行布局

//弹出方法

 
 //显示
func showPlayListView(){
UIApplication.sharedApplication().keyWindow?.addSubview(self)
//动画从下向上进入
var vbFrame:CGRect = self.viewBackground.frame
vbFrame.origin.y=vbFrame.origin.y+vbFrame.size.height
self.viewBackground.frame=vbFrame
UIView.animateWithDuration(0.15, animations: { () -> Void in
var vbFrame:CGRect = self.viewBackground.frame
vbFrame.origin.y=vbFrame.origin.y-vbFrame.size.height
self.viewBackground.frame=vbFrame
});
}
 

//关闭方法(将关闭按钮,和viewTouch的点击事件,关联此方法)

 //关闭
@IBAction func closePlayListView(sender: AnyObject) {
self.removeFromSuperview()
}

//弹出我关闭方法都写好了,下面就在ViewController页,调用此视图让其弹出来

 @IBAction func showPlayList(sender: UIButton) {
NSLog("----click---")
var playList:PlayListView=NSBundle.mainBundle().loadNibNamed("PlayListView", owner: self, options: nil).last as PlayListView
playList.showPlayListView()
}

//六、请求网络数据

请求使用到一个封装类:HttpProtocol.swift

 
import UIKit

protocol HttpProtocol{
func didRecieveResults(results:NSDictionary)
} class HttpController:NSObject{ var delegate:HttpProtocol? func onSearch(url:String){
NSLog("请求地址:%@", url)
var nsUrl:NSURL=NSURL(string:url)!
var request:NSURLRequest=NSURLRequest(URL:nsUrl)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue(), completionHandler: {(response:NSURLResponse!,data:NSData!,error:NSError!)->Void in
if (data != nil){
var jsonResult:NSDictionary=NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
self.delegate?.didRecieveResults(jsonResult)
}
})
}
}
 

新建一个实体类Song.swift用来存放请求的数据

 
import Foundation
class Song: NSObject {
var adtype:NSNumber = 0.0
var aid:NSString = ""
var album:NSString = ""
var albumtitle:NSString = ""
var artist:NSString = ""
var company:NSString = ""
var kbps:NSNumber = 0.0
var length:NSNumber = 0.0
var like:NSNumber = 0.0
var monitor_url:NSString = ""
var picture:NSString = ""
var public_time:NSString = ""
var rating_avg:NSString = ""
var sha256:NSString = ""
var sid:NSString = ""
var songlists_count:NSNumber = 0.0
var ssid:NSString = ""
var subtype:NSString = ""
var title:NSString = ""
var url:NSString = ""
}
 

将请求的数据转化了实体集合

  var eHttp:HttpController = HttpController()
 //请求网络数据
eHttp.delegate=self
eHttp.onSearch("http://douban.fm/j/mine/playlist?channel=1")//华语
 
  //请求网络数据结果
func didRecieveResults(results:NSDictionary){
NSLog("请求到的数据:%@", results)
if (results["song"] != nil) {
let resultData:NSArray = results["song"] as NSArray
let list:NSMutableArray = NSMutableArray() for(var index:Int=0;index<resultData.count;index++){
var dic:NSDictionary = resultData[index] as NSDictionary
var song:Song=Song()
song.setValuesForKeysWithDictionary(dic as NSDictionary)
list.addObject(song)
}
self.tableData=list
self.setCurrentSong(list[0] as Song)
}
}
 

//七、*将请求后的第1条数据设置为当前将要播发的歌曲

绑定当前歌曲信息

 
  //设置当前播放的音乐
func setCurrentSong(curSong:Song){
currentSong=curSong
photo.image=getImageWithUrl(currentSong.picture)
backgroundImageView.image=photo.image
titleLabel.text=currentSong.title
artistLabel.text=currentSong.artist
playButton.selected=false
playTimeLabel.text="00:00"
self.progressSlider.value=0.0
self.rotationAnimation()
}
 

//八、*播放音乐

  self.audioPlayer.stop()
self.audioPlayer.contentURL=NSURL(string:currentSong.url)
timer?.invalidate()
timer=NSTimer.scheduledTimerWithTimeInterval(0.4, target: self, selector: "updateTime", userInfo: nil, repeats: true)
 
 @IBAction func playButtonClick(sender: UIButton) {
if sender.selected {
//暂停播放
self.audioPlayer.pause()
pauseLayer(photo.layer)
}else{
//开始/继续播放
self.audioPlayer.play()
resumeLayer(photo.layer)
}
sender.selected = !sender.selected
} //更新播放时间
func updateTime(){
let c=audioPlayer.currentPlaybackTime
// audioPlayer.endPlaybackTime
if c>0.0 {
let t=audioPlayer.duration
let p:CFloat=CFloat(c/t)
progressSlider.value=p;
let all:Int=Int(c)//共多少秒
let m:Int=all % 60//秒
let f:Int=Int(all/60)//分
var time=NSString(format:"%02d:%02d",f,m)
playTimeLabel.text=time
}
}
 

//九、*当点击播放或暂停时,需要将图片的动画动起来或停止动画

使用到以下两个方法

 
//停止Layer上面的动画
func pauseLayer(layer:CALayer){
var pausedTime:CFTimeInterval=layer.convertTime(CACurrentMediaTime(), fromLayer: nil)
layer.speed=0.0
layer.timeOffset=pausedTime
} //继续Layer上面的动画
func resumeLayer(layer:CALayer){
var pausedTime:CFTimeInterval = layer.timeOffset
layer.speed=1.0
layer.timeOffset=0.0
layer.beginTime=0.0
var timeSincePause:CFTimeInterval=layer.convertTime(CACurrentMediaTime(), fromLayer: nil)-pausedTime
layer.beginTime=timeSincePause
}
 

最终效果:

源码下载地址:http://download.csdn.net/detail/fangwulongtian/8565487

原文出自:http://www.cnblogs.com/wuxian/p/4394094.html 转载就注明来源

Swift实战-QQ在线音乐(第一版)的更多相关文章

  1. Swift实战-QQ在线音乐(第二版)

    此版本使用百度音乐接口,原因是豆瓣接口很多歌曲没办法找到歌词. 此版本添加了歌词的显示.上一曲.下一曲的实现.歌曲列表指明当前歌曲. 下面来看一下实现过程>>> 一.项目准备: 百度 ...

  2. Swift实战-QQ在线音乐(AppleWatch版)

    1.打开项目QQMusic,然后点菜单:“File-New-Target”添加appleWatch扩展项 2.选择Swift语言,把Include Notification Scene前的勾去掉 (项 ...

  3. Swift实战-豆瓣电台(五)播放音乐

    观看地址 http://v.youku.com/v_show/id_XNzMwODM0MzI0.html 在这节里面,我们简单学习了一下MediaPlayer的使用 引入媒体框架 import Med ...

  4. Andriod小项目——在线音乐播放器

    转载自: http://blog.csdn.net/sunkes/article/details/51189189 Andriod小项目——在线音乐播放器 Android在线音乐播放器 从大一开始就已 ...

  5. Swift实战-豆瓣电台(九)简单手势控制暂停播放(全文完)

    Swift实战-豆瓣电台(九)简单手势控制暂停播放 全屏清晰观看地址:http://www.tudou.com/programs/view/tANnovvxR8U/ 这节我们主要讲UITapGestu ...

  6. Swift实战-豆瓣电台(八)播放进度与时间

    视频观看地址:http://www.tudou.com/programs/view/4mEtz8S72k0/?resourceId=399000367_06_02_99 这节主要内容是NSTimer, ...

  7. Swift实战-豆瓣电台(七)显示动画

    youku观看地址http://v.youku.com/v_show/id_XNzMxODQzNDIw.html 这是一个很酷的动画效果.特别是数据多的时候 知识点 在单元格(Cell)显示方法中设置 ...

  8. Swift实战-豆瓣电台(六)视图跳转,传参及回跳

    youku观看地址:http://v.youku.com/v_show/id_XNzMxMzQ3MDcy.html 要点 在ChannelController里面声明一个代理 这个代理遵循我们自定义的 ...

  9. 在线音乐API的研究 (Part 2.1)

    本文转载于:http://www.cnblogs.com/osmondy/p/LyricApi.html 最近,在优化一个自己写的音乐播放器.主要目的是回顾.归纳,并希望能够写出一个属于自己的comm ...

随机推荐

  1. HDU1181【有向图的传递闭包】

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1181 题意很简单. 有用并查集做的.我这里用传递闭包做. 有向图的传递闭包采用Floyd思想,可以判断 ...

  2. 解决外贸电商难题,PayPal中国外贸电商大会圆满礼成

        在全球经济一体化的背景下,越来越多的中国企业将目光转移到了海外.对中国的企业而言,要想将生意做到海外大致有两种方法可供选择,一是到海外设立分支机构或者分公司,二是通过外贸电子商务平台实现交易. ...

  3. 各浏览器对 window.open() 的窗口特征 sFeatures 参数支持程度存在差异

    标准参考 无. 问题描述 使用 window.open 方法可以弹出一个新窗口,其中 open 方法的 sFeatures 参数选项在各浏览器中支持程度不一,这有可能导致同样的代码使各浏览器中弹出窗口 ...

  4. 【转】emulator: ERROR: Could not load OpenGLES emulation library: lib64OpenglRender.so

    [转]emulator: ERROR: Could not load OpenGLES emulation library: lib64OpenglRender.so ./emulator64-arm ...

  5. 语句分类及if语句

    一.语句分类: 1.顺序语句2.分支语句 if语句.switch语句 3.循环语句 (1)初始条件 (2)循环条件 (3)循环体 (4)状态改变 二.if语句: 1.if语句4中情况: if(条件){ ...

  6. 无法编辑的word解密

    打开文档后,将其另存为XML文件,然后用UltraEdit(或者EditPlus,下载华军里搜索一下就行了)这个编辑软件打开刚刚存储的 XLM文件,查找<w:documentProtection ...

  7. IOS 指纹识别的简单使用

    首先导入LocalAuthentication框架 然后导入头文件 #import <LocalAuthentication/LAPublicDefines.h> - (void)begi ...

  8. myEclipse快捷键及其常用设置

    快捷键:    查找替换:ctrl + f    复制行: ctrl + alt + down    删除行: ctrl + d    插入行: shift + enter, ctrl + shift ...

  9. 为什么cp很多小文件非常慢——对cp和rm命令的一些思考

    linux中的文件复制命令——CP linux中文件剪切的命令——MV 1.问题背景 今天在某个目的动作过程中想把一个文件夹下的文件复制到另外的一个文件夹下 cp -fr   ./dir1/   /d ...

  10. 高级UNIX环境编程2

    perror("error:") ;  strerror 日历时间:time_t (1970.1.1开始的秒数)     struct timeval (秒数和微秒)  struc ...