//一、*项目准备

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. HDU 3625 Examining the Rooms

    题目大意:有n个房间,n!个钥匙,在房间中,最多可以破k扇门,然后得到其中的钥匙,去开其它的门,但是第一扇门不可以破开,求可以打开所有门的概率. 题解:首先,建立这样的一个模型,题目相当于给出一个图, ...

  2. How many prime numbers(求素数个数)

    How many prime numbers Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/O ...

  3. HDU1284钱币兑换问题( 母函数打表)

    题意:在一个国家仅有1分,2分,3分硬币,将钱N兑换成硬币有很多种兑法.请你编程序计算出共有多少种兑法. 原题http://acm.hdu.edu.cn/showproblem.php?pid=128 ...

  4. linux内核源码阅读之facebook硬盘加速利器flashcache

    从来没有写过源码阅读,这种感觉越来越强烈,虽然劣于文笔,但还是下定决心认真写一回. 源代码下载请参见上一篇flashcache之我见 http://blog.csdn.net/liumangxiong ...

  5. windows下使用python googleprotobuf

    首先下载:protobuf-2.5.0.tar.gz 和protoc-2.5.0-win32.zip.两者的版本要对应: 将下载的google protobuf解压,会看到一个python目录,Win ...

  6. Sql Server Convert函数转换Datetime类型数据

    0 Feb 22 2006 4:26PM CONVERT(CHAR(19), CURRENT_TIMESTAMP, 0) 1 02/22/06 CONVERT(CHAR(8), CURRENT_TIM ...

  7. C#中泛型、程序集一些基本运用(Fifteenth Day)

    今天主要在学习了泛型和程序集以及一些细碎的知识的运用.下面我就把今天所学的总结一下. 理论: 泛型: * 英文名字是Generic,可以让多个类型共享一组代码,泛型允许我们声明类型参数化,可以用不同的 ...

  8. HTML5 DTD

    HTML5/HTML 4.01/XHTML 元素和有效的 DTD 下面的表格列出了所有的 HTML5/HTML 4.01/XHTML 元素,以及它们会出现在什么文档类型 (DTD) 中: 标签 HTM ...

  9. clear伪类使用

    都知道float会脱离文档流  用什么办法撑开父元素呢? 手动在本区块的所有float元素之后加上一个块元素并对其添加clear:both 可以 但是这样还要再去修改html页面  而且多了一个仅仅是 ...

  10. Error creating bean with name 'enableRedisKeyspaceNotificationsInitializer'

    @Configuration public class HttpSessionConfig { @Bean public static ConfigureRedisAction configureRe ...