//一、*项目准备

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. Qt WebKit and HTML5 geolocation | Qt Project forums | Qt Project

    Qt WebKit and HTML5 geolocation | Qt Project forums | Qt Project Qt WebKit and HTML5 geolocation   I ...

  2. return view详解(转载)

    1.return View(); 返回值 类型:System.Web.Mvc.ViewResult将视图呈现给响应的 View() 结果. 注释 View() 类的此方法重载将返回一个具有空 View ...

  3. linq to sql用partial扩展属性,创建一个部分类(用于多表连接)

    1.在窗体中创建dataGridView显示表: using System; using System.Collections.Generic; using System.ComponentModel ...

  4. MySQL支持emoji

    方案1: 应用层支持 MySQL默认的数据库编码是utf8,对于emoji文字是不能直接存储的,要想存储emoji,有许多库支持对emoji的转换,例如将

  5. (Problem 57)Square root convergents

    It is possible to show that the square root of two can be expressed as an infinite continued fractio ...

  6. Kettle之数据抽取、转换、装载

    Kettle 官网 ETL利器Kettle实战应用解析系列 利用kettle组件导入excel文件到数据库 kettle中实现动态SQL查询 java中调用kettle转换文件

  7. QComboBox 添加图片(自带addItem函数就有这个功能,从没有注意过)

    方法:    使用 QComboxBox::addItem(QIcon, QString); 示例: 点击(此处)折叠或打开 QComboBox *combo_status = new QComboB ...

  8. use utf8

    [root@wx03 0724]# cat a2.pl use Encode; my $a=<STDIN>; my $b=encode_utf8('微信'); print "\$ ...

  9. C# RSA在服务上使用出现拒绝方法错误的解决方法

    在做一个快钱接口的时候,遇到了.net RSA加密无法在一台win2008服务器上运行正常,更换到Win2003服务器后出现问题,具体表现如下: “/”应用程序中的服务器错误. ----------- ...

  10. 【Eclipse】Tomcat 一直处于starting状态,项目却已成功启动

    是因为Eclipse里面设置了代理.preference-network connections-activity provider-direct-应用.重启tomcat即可.