当我从一个视图导航到另一个视图时,如何让音乐持续播放?

How do I get music to persist as I navigate from view to view?

所以,我已经掌握了使用 iOS 中的一个视图演奏 sounds/music 的艺术,但我现在正在尝试为音乐艺术家制作一个更强大的应用程序。到目前为止,它涉及从 "menu" ViewController 到他的个人简介、演出时间和 "Listening Room" 等。到目前为止,我创建了一个 "AudioManager" class :

import UIKit
import AVFoundation
import MediaPlayer

class AudioManager: NSObject {

    let defaltSong = ["Hell&BackCaf/01 Black Sheep", "caf"]
    weak var delegate : PlayerDelegate?
    var musicPlayer1 = AVAudioPlayer()
    var trackNumber = 0

    var musicAudioPath = NSBundle.mainBundle().pathForResource("Hell&BackCaf/01 Black Sheep", ofType: "caf")
    var musicAudioPathURL = NSURL()
    var error:NSError? = nil


    var songList = [["Hell&BackCaf/01 Black Sheep", "caf"], ["Hell&BackCaf/02 Hell & Back", "caf"], ["Hell&BackCaf/03 Save Me", "caf"], ["Hell&BackCaf/04 Broken feat. Hillary Dodson", "caf"], ["Hell&BackCaf/05 Do Or Die", "caf"], ["Hell&BackCaf/06 Divided", "caf"]]

    func ButtonPlay(song: NSString, type: NSString) {

        error = nil

        musicAudioPath = NSBundle.mainBundle().pathForResource(song as String, ofType: type as String)

        musicAudioPathURL = NSURL(fileURLWithPath: self.musicAudioPath!)!

        musicPlayer1 = AVAudioPlayer(contentsOfURL: musicAudioPathURL, error: &error)

        musicPlayer1.prepareToPlay()

        musicPlayer1.play()
    }

    func loadFirstSong() {

        error = nil

        musicAudioPath = NSBundle.mainBundle().pathForResource("Hell&BackCaf/01 Black Sheep", ofType: "caf")
        musicAudioPathURL = NSURL(fileURLWithPath: self.musicAudioPath!)!
        musicPlayer1 = AVAudioPlayer(contentsOfURL: musicAudioPathURL, error: &error)
        if error == nil {
            musicPlayer1.prepareToPlay()
        } else {
            println(error)
        }


    }


    func advanceTrack(){

        if trackNumber < songList.count - 1 {

            self.trackNumber++

            ButtonPlay(songList[trackNumber][0], type: songList[trackNumber][1])            
        } else {

            trackNumber = 0

            ButtonPlay(songList[trackNumber][0], type: songList[trackNumber][1])
        }
    }

    func previousTrack(){

        if trackNumber > 0 {

            trackNumber--

            ButtonPlay(songList[trackNumber][0], type: songList[trackNumber][1])

        } else {

            trackNumber = songList.count - 1

            ButtonPlay(songList[trackNumber][0], type: songList[trackNumber][1])
        }

    }

    func audioPlayerDidFinishPlaying(AVAudioPlayer!, successfully: Bool) {
        self.delegate?.soundFinished(self)
        println("song over")
    }



}

然后我在我的 MusicRoom 中使用了它ViewController:

import UIKit
import AVFoundation

class MusicRoomViewController: UIViewController, AVAudioPlayerDelegate {

    let audioManager = AudioManager()

    @IBAction func pressedBackButton(sender: UIButton) {
        audioManager.previousTrack()
    }

    @IBAction func pressedPlayButton(sender: UIButton) {
        audioManager.musicPlayer1.play()
    }

    @IBAction func pressedForwardButton(sender: UIButton) {
        audioManager.advanceTrack()
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        audioManager.loadFirstSong()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    override func viewWillDisappear(animated: Bool) {

        if self.isMovingFromParentViewController()
        {
            audioManager.musicPlayer1.play()
        }
    }

}

但是现在,当我导航到该应用程序的任何其他 'page' 时,音乐会停止。经过研究,我知道我做错了,但我似乎无法弄清楚我需要做什么才能保持音频播放直到应用程序关闭或用户按下停止键(这还不存在,我知道)。有什么想法吗??

您必须将 AudioManager class 设为单例。正在发生的事情是,一旦您离开创建它的视图,您正在创建的 AudioManager 实例就会被释放。单例对象在首次访问后创建,并将一直存在于内存中,直到应用程序的生命周期结束或它被显式释放。有关 Swift 单例的更多信息,请查看 this page。这是一个很有用的学习模式。

对AudioManager进行如下修改(取自上述网站):

private let _AudioManagerSharedInstance = AudioManager()

class AudioManager {
    static let sharedInstance = AudioManager()
}

使用 AudioManager.sharedInstance 访问 AudioManager,例如您可以调用 AudioManager.sharedInstance.previousTrack()

您可以创建一个单例,或者在您的 AppDelegate class 中实例化 AudioManager 并像这样引用它:

AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];

appDelegate.audioManger...