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

  • 相关阅读:
    面向对象的继承关系体现在数据结构上时,如何表示
    codeforces 584C Marina and Vasya
    codeforces 602A Two Bases
    LA 4329 PingPong
    codeforces 584B Kolya and Tanya
    codeforces 584A Olesya and Rodion
    codeforces 583B Robot's Task
    codeforces 583A Asphalting Roads
    codeforces 581C Developing Skills
    codeforces 581A Vasya the Hipster
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/4892506.html
Copyright © 2011-2022 走看看