zoukankan      html  css  js  c++  java
  • Swift实战-QQ在线音乐(第一版)

    //一、*项目准备

    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 转载就注明来源

  • 相关阅读:
    XML文件的解析—DOM、SAX
    JSP :使用<%@include%>报Duplicate local variable path 错误
    XML文件的DTD编写
    DOM生成XML文件
    ArrayList增加扩容问题 源码分析
    实时事件统计项目:优化flume:用file channel代替mem channel
    CDH离线数据导入solr:利用MapReduceIndexerTool将json文件批量导入到solr
    solrconfig.xml介绍
    Solr Update插件自定义Update Chain按条件更新索引
    实时事件统计项目:优化solr和morphline的时间字段
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/4892506.html
Copyright © 2011-2022 走看看