2016-05-29 27 views
2

我有一個奇怪的小問題AVAudioPlayer,我找不到一個很好的整潔的解決方案。我使用下面的函數在我的應用程序的菜單屏幕上播放一些背景音樂:AVAudioPlayer在繼續播放之後繼續播放,並在返回到原始視圖控制器時重新啓動 - 我該如何阻止它?

func startMusic() { 
    do { 
     try musicPlayer = AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("menu_music", ofType: "mp3")!)) 
    } catch let err as NSError { 
     print (err.debugDescription) 
    }  
    musicPlayer.prepareToPlay() 
    musicPlayer.numberOfLoops = -1 
    musicPlayer.play() 
} 

我把它在viewDidLoad這樣的:

override func viewDidLoad() { 
     super.viewDidLoad()    
     startMusic()   
    } 

到目前爲止好。

該菜單有幾個按鈕,通過所有在界面生成器中創建的段落將用戶引導至其他屏幕 - 無程序化段落。

第一個問題是音樂在其他屏幕加載時繼續播放。在大多數情況下,這實際上是一個不錯的,理想的效果,但我想知道是否有停止方法,除了創建菜單按鈕操作,包括musicPlayer.stop()musicPlayer.pause()。例如,一個視圖控制器可以停止在另一個視圖中啓動的AVAudioPlayer

我遇到的更嚴重的問題是,當我回到菜單屏幕(再次,通過啓動界面生成器的按鈕創建了segue)時,音樂的副本開始播放原始聽起來很可怕),似乎沒有辦法阻止它或檢查它是否在播放。如果更多的菜單選項被點擊然後返回,但更多音樂的副本開始播放。

我已經試過

if (!musicPlayer.playing) { 
    musicPlayer.play() 
} 

if (musicPlayer == nil) { 
    musicPlayer.play() 
} 

以及停止和每次開機的球員,但我仍然得到同樣的音樂播放在彼此的多個副本。就好像有多個同名的無法停止的音樂播放器或者在後臺運行相同視圖控制器的多個副本。

我意識到我可能錯過了一些絕對必要的東西,但谷歌沒有給我提供答案,我知道堆棧溢出的好人不會讓我失望。

謝謝。

+0

'if(musicPlayer == nil)',如果你的'musicPlayer'是'nil',你可能想重新創建它。也許你的意思是'if(musicPlayer!= nil)'? –

+0

對不起,沒有。我試圖做的只是在音樂尚未播放時纔開始播放。 – Westside

+0

你的'if(!musicPlayer.playing)'應該做到這一點。有沒有其他地方可以創建你的'AVAudioPlayer'? –

回答

1

原來...

這是一個與我建立在Interface Builder中塞格斯(這可能是錯誤的所有一起)的方式做。如果你按住ctrl鍵從一個按鈕拖到一個視圖控制器來創建一個segue,然後執行相同的操作(按住CTRL鍵從一個按鈕拖回第一個視圖控制器)來創建'back'segue,那麼這看起來會創建多個實例的AVAudioPlayer(或可能是整個菜單視圖控制器),這會產生由多個版本的音樂互相播放引起的令人討厭的效果。

無論其如果使用UNWIND SEGUE要回的菜單,然後在音樂播放各地,但不會對返回菜單重新開始。整潔。

爲了停止需要停止它的菜單選項的音樂,唯一的方法似乎是停止音樂然後以編程方式調用segue的動作。

在界面構建器中創建所有的細節很簡單,但很明顯,總是需要代碼行。

2

在你的主視圖控制器的viewWillDisappear你可以stop你的AVAudioPlayer

例如:

override func viewWillDisappear(animated: Bool) { 
    musicPlayer.stop() 
} 
+0

謝謝,這是一個很好的開始。這會停止任何菜單選項的音樂,但是您是否知道一種讓播放器繼續播放的方法,同時可以看到第二個屏幕,而不會在播放器返回到菜單時開始複製? – Westside

相關問題