2016-05-29 57 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

相关问题