Swift 3:每次视图控制器加载时,背景音乐都会再次播放

时间:2016-12-22 13:51:46

标签: ios swift3 avaudioplayer

视频控制器加载后,我的背景音乐会播放。这很棒,但每次用户返回该屏幕时,它都会再次播放。并将自己分层成一个不连贯的混乱。我需要播放一次音乐并继续播放,直到用户在设置中将其关闭。

我从我编写的代码中了解到。加载视图后会创建audioPlayer,然后检查布尔isPlaying是否设置为false。如果是,则执行playMusic功能。如果设置为true它应该什么都不做。我很困惑为什么它会在上一次迭代之前再次播放音乐。

每次加载视图时都可以创建音频播放器吗?如果是这样我将如何解决这个问题?

加载应用后,会向用户显示一个开始屏幕。音乐开始在那里播放。

然后他们按下开始,购买提示或设置。为了回到上一个屏幕,你点击了一个后退按钮。设置应用程序的方式,总是会让您回到开始屏幕。 segues只是在那里设置的。我控制拖动到下一个视图控制器并选择show选项。

import UIKit
import AVFoundation

class ViewController: UIViewController {

    var audioPlayer = AVAudioPlayer()

    @IBOutlet weak var  musicToggle: UIButton!

    var isPlaying = false

    @IBAction func musicTogglebtn(_ sender: Any) {

    }

    override func viewDidLoad() {
        super.viewDidLoad()

        do {
            audioPlayer = try AVAudioPlayer(contentsOf: URL.init(fileURLWithPath: Bundle.main.path(forResource: "weiss", ofType: "mp3")!))
            audioPlayer.prepareToPlay()
        } catch {
            print(error)
        }

        if isPlaying == false {
            playMusic()
        } else {
            return
        }
    }

    func playMusic() {
        audioPlayer.play()
        isPlaying = true
    }


    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}

3 个答案:

答案 0 :(得分:1)

您未提供的关键信息是用户如何进出此屏幕?

如果您在其上方显示/推送另一个视图控制器并且用户解除/弹出该视图控制器,则会显示带有音频播放器的视图控制器,其状态仍然完好。

如果你弹出/关闭你的ViewController然后呈现一个新的,或者继续推送/呈现新副本,那么每个视图控制器将拥有它自己的状态,以及它自己的音频播放器所以你会发现越来越多的声音在彼此之上播放。

我的猜测是你的问题。

发布有关用户如何导航视图控制器的信息,我们可以帮助您进行排序。

编辑:

根据您的回复,我现在了解您的问题。

声音播放问题是更大问题的症状。您已设置后退按钮以触发show segue。这会创建一个额外的,全新的视图控制器副本,该副本将添加到导航堆栈的顶部。这是错误的,会导致很多问题。

您应该设置导航控制器以显示导航栏。当你这样做时,它会为你设置一个后退按钮,后退按钮会将前视图控制器从堆栈中弹出并暴露下面的那个。这是后退按钮的预期行为。

如果您想让后退按钮一直带到开始屏幕,那么您应该从后退按钮中移除segue链接,而是将其连接到发送消息IBAction的{​​{1}}到导航控制器。

这将导致您的下一个问题,即当您单击声音后退按钮时,您将关闭当前视图控制器并失去对音频播放器的访问权。

您应该将声音播放控件移动到中央声音管理器对象。这对单身人士来说是一个很好的用途。 (请查看。)向声音管理器单例添加方法,让您启动和停止声音,并在显示视图控制器时调用声音播放方法,并在您希望它停止时停止播放声音。

答案 1 :(得分:1)

查看在每次通话时加载意味着,考虑如何呈现屏幕非常重要。例如,假设您在ViewController A中执行此操作,并且您已移至View Controller B.现在,您如何从View Controller B进入A非常重要。如果您再次展示View Controller A,则表示再次加载View Did Load。否则,如果您弹出或关闭视图控制器并进入View Controller A意味着它将无法加载。

答案 2 :(得分:0)

当您导航到ViewController时,isPlaying将始终为false,您需要确保isPlaying是全局可访问的,或者可以使用dispatch_once GCD参考此文档Dispatch once in Swift 3

或者您甚至可以尝试将isPlaying作为属性使用共享类,但这并不完全干净。