前段时间用Swift练手写了这么一个demo,后来有朋友希望能出个教程,于是就捣鼓出这么一个系列教程,内容包括准备、界面布局、获取网络数据、歌曲列表的展现、播放音乐、视图跳转传参及回跳、显示动画、播放进度与时间以及简单手势控制暂停播放九个部分。
Swift实战-豆瓣电台(一)准备
我们现在看看我们要做一个什么样的东西,观看地址:http://v.youku.com/v_show/id_XNzI4ODY2Mjky.html
布局
通过上面这张图我们可以看出整个 demo 有两个视图,视图一用来播放音乐,视图二用来选择频道。
视图一
ImageView用来显示音乐的图片
TableView用来显示音乐列表
Progress用来显示播放进度
Label用来显示播放时间
Button用来切换视图
视图二
Lbale显示“选择频道”
Tableview用来显示频道列表
知识要点
组件:
ImageView
TableView
TableViewCell
Progress
Label
Button
MediaPlayer
知识点:
视图之间的跳转,传参,回跳
协议
异步获取数据
Json解析
动画效果
豆瓣API
频道列表
http://www.douban.com/j/app/radio/channels
歌曲列表
http://douban.fm/j/mine/playlist?channel=0
#p#
Swift实战-豆瓣电台(二)界面布局
观看地址:http://v.youku.com/v_show/id_XNzMwMDg4NzAw.html
这节的内容主要是storyboard的操作。
有以下几个知识点
1.TableView的DataSource与Delegate的设定。我们将其绑定在 ViewController 上,使之遵循 UITableViewDataSource,UITableViewDelegate 协议来实现。然后我们实现了两个函数,一个返回了 TableView 中行数。也就是 TableView 里面有多少条数据。
- func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int{
- return 10
- }
一个返回了TableView的单元格(cell)实例,也就是单元格长什么样
- func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!{
- let cell=UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "douban")
- return cell
- }
2. 单元格的识别。在 storyboard 中选中 cell。然后设置 ldentifier 的值来实现。ldentifier 的值与下列语句中的 reuseIdentifier 的值(”douban”)对应。
- let cell=UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "douban")
3. 从频道列表中返回主界面如果按照主界面跳转到频道列表的方式则会不断地产生新的主界面。所以用 dismissViewControllerAnimated 函数来回跳
- self.dismissViewControllerAnimated(true, completion: nil)
本节高清视频及项目文件下载地址:http://pan.baidu.com/s/1sjHd5qX
#p#
Swift实战-豆瓣电台(三)获取网络数据
观看地址:http://v.youku.com/v_show/id_XNzMwMzQxMzky.html
这节内容,我们先说了怎么将storyboard中的组件在类中进行绑定。然后写了一个类用来获取网络数据,同时定义了一个协议,在获取数据后进行回调。之后对json数据进行解析,转化为一个字典。
知识点
异步获取数据
- 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)
NSURL 和 NSURLRequest 都是使用简单却难以简单说明的东西。意会吧。
NSURLConnection.sendAsynchronousRequest 方法中的 NSOperationQueue.mainQueue() 将获取数据这个任务放进主队列。
completionHandler:完成任务后函数调用。
Json解析
- var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
NSJSONReadingOptions.MutableContainer:设置返回的对象是可以随时添加新值的Mutable 类型的对象
协议
协议和其他语言中的接口类似,我们在数据获取类中设置一个遵循该协议的成员,当数据获取完毕后,该成员执行某个方法来使用数据。我们如果不用协议用具体的某个类也是可以的。但就失去了灵活性。
高清视频及代码下载地址:http://pan.baidu.com/s/1sjHd5qX
#p#
Swift实战-豆瓣电台(四)歌曲列表的展现
观看地址 : http://v.youku.com/v_show/id_XNzMwNDE0OTA4.html
这节的主要内容是如何利用 cell 展现获取到的数据。
首先申明两个数组来储存我们获取到的数据
- var tableData:NSArray=NSArray()
- var channelData:NSArray=NSArray()
tableData 是主界面上歌曲列表要用的数据。所以在 func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) 这个方法中要返回tableData的数量
- func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int{
- return tableData.count
- }
然后我们把tableData中的数据填充到主界面的TableView中
- let cell=UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "douban")
- let rowData:NSDictionary=self.tableData[indexPath.row] as NSDictionary
- cell.text=rowData["title"] as String
- cell.detailTextLabel.text=rowData["artist"] as NSString
接着我们在显示缩略图的时候先给一张默认的图片
- cell.image=UIImage(named:"detail.jpg")
然后我们去抓取网络图片,同样,是用异步的方式。为了提高性能,我们对获取的图片做了一个缓存
- var imageCache = Dictionary<String,UIImage>()
通过图片的地址来缓存UIImage
- let url=rowData["picture"] as String
- let image=self.imageCache[url] as?UIImage
- if !image?{
- let imgURL:NSURL=NSURL(string:url)
- let request:NSURLRequest=NSURLRequest(URL: imgURL)
- NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue(), completionHandler: {(response:NSURLResponse!,data:NSData!,error:NSError!)->Void in
- var img=UIImage(data:data)
- cell.image=img
- self.imageCache[url]=img
- })
- }else{
- cell.image=image
- }
本节高清视频和代码下载地址:http://pan.baidu.com/s/1sjHd5qX
#p#
Swift实战-豆瓣电台(五)播放音乐
观看地址:http://v.youku.com/v_show/id_XNzMwODM0MzI0.html
在这节里面,我们简单学习了一下MediaPlayer的使用
引入媒体框架
- import MediaPlayer
声明一个媒体播放器
- var audioPlayer:MPMoviePlayerController=MPMoviePlayerController();
播放暂停操作
- self.audioPlayer.stop()
- self.audioPlayer.contentURL=NSURL(string:url)
- self.audioPlayer.play()
本节高清视频及源码下载地址:http://pan.baidu.com/s/1sjHd5qX
#p#
Swift实战-豆瓣电台(六)视图跳转,传参及回跳
youku观看地址:http://v.youku.com/v_show/id_XNzMxMzQ3MDcy.html
要点
在ChannelController里面声明一个代理
这个代理遵循我们自定义的协议ChannlePrococol。
遵循这个协议的主界面类在注入后有一个回调方法onChangeChanne将所选择的频道返回。
prepareForSegue方法
这个方法是在准备跳转的时候执行的。在这里面我们能拿到将要跳转的视图类segue.destinationViewController,这时候就能设置这个类的代理,并将数据传过去了
高清视频与代码下载地址:http://pan.baidu.com/s/1sjHd5qX
#p#
Swift实战-豆瓣电台(七)显示动画
youku观看地址:http://v.youku.com/v_show/id_XNzMxODQzNDIw.html
这是一个很酷的动画效果。特别是数据多的时候
知识点
在单元格(Cell)显示方法中设置动画
- func tableView(tableView: UITableView!, willDisplayCell cell: UITableViewCell!, forRowAtIndexPath indexPath: NSIndexPath!){
- cell.layer.transform = CATransform3DMakeScale(0.1, 0.1, 1)
- UIView.animateWithDuration(0.25, animations: {
- cell.layer.transform=CATransform3DMakeScale(1, 1, 1)
- })
- }
willDisplayCell 顾名思义。就是在Cell显示之前。设置cell的层(layer)的变换(transform)为CATransform3DMakeScale做一个缩放动画。X,y方向的缩放从0.1到1
高清视频与代码下载地址:http://pan.baidu.com/s/1sjHd5qX
#p#
Swift实战-豆瓣电台(八)播放进度与时间
视频观看地址:http://www.tudou.com/programs/view/4mEtz8S72k0/?resourceId=399000367_06_02_99
这节主要内容是 NSTimer,UIProgressView,MPMoviePlayerController 类的使用
NSTimer
实例化:
- timer=NSTimer.scheduledTimerWithTimeInterval(0.4, target: self, selector: "onUpdate", userInfo: nil, repeats: true)// 实例化后即启动定时器,0.4秒后开始第一次触发
0.4 是间隔时间;target 是发送对象;selector 是触发的方法;userInfo 此参数可以为 nil,当定时器失效时,由你指定的对象保留和释放该定时器;repeats 是否重复。
立即触发
- fire()
停止
- invalidate()
UIProgressView
设置进度条进度
- progressView.progress=0.0
带动画
- progressView.setProgress(p, animated: true)
MPMoviePlayerController
audioPlayer.currentPlaybackTime 已经播放的时间(秒)
audioPlayer.duration 总时间(秒)
秒钟分钟算法
总时间除以60的余数就是秒钟
总时间除以60的商就是分钟
因为我们的展现形式是00:00
所以当数字小于10的时候进行字符串拼接补0例如01,02
本节高清视频和代码下载地址:http://pan.baidu.com/s/1sjHd5qX
#p#
Swift实战-豆瓣电台(九)简单手势控制暂停播放
全屏清晰观看地址:http://www.tudou.com/programs/view/tANnovvxR8U/
这节我们主要讲 UITapGestureRecognizer 和 MPMoviePlayerController
知识点
UITapGestureRecognizer
关联storyboard上的UITapGestureRecognizer
- @IBOutlet var tap:UITapGestureRecognizer=nil //注意要设置为nil
增加手势识别
- addGestureRecognizer(tap)
移除手势识别
- removeGestureRecognizer(tap)
关联Action
- @IBAction func onTap(recognizer: UITapGestureRecognizer)
通过 recognizer.view 可以判断点击了哪个组件
- @IBAction func onTap(recognizer: UITapGestureRecognizer){
- if recognizer.view==btnPlay {
- btnPlay.hidden=true
- audioPlayer.play()
- btnPlay.removeGestureRecognizer(tap)
- iv.addGestureRecognizer(tap)
- }else if recognizer.view==iv {
- btnPlay.hidden=false
- audioPlayer.pause()
- btnPlay.addGestureRecognizer(tap)
- iv.removeGestureRecognizer(tap)
- }
- }
MPMoviePlayerController
播放
- play()
暂停
- pause()
本节高清视频和代码下载地址:http://pan.baidu.com/s/1sjHd5qX
原帖地址:http://www.cnblogs.com/sandal1980/p/3812715.html 作者:sandal1980(博客)