如何在声音停止播放后执行segue

时间:2017-11-16 14:41:54

标签: ios audio segue launch

我在Main.Storyboard中制作了一个自定义的LaunchScreen,使声音实际上来自LaunchScreen。声音工作正常,也可以到下一个视图控制器。唯一的问题是segue在声音停止播放之前发生。我希望声音在制作之前完成。逻辑上,它应该工作,因为performSegue直接在.play()之后。但似乎两者同时发生。这是我的代码:

 super.viewDidLoad()

    //PLAY SOUND CLIP//
    let musicFile = Bundle.main.path(forResource: "fanfare", ofType: ".mp3")
    do {
        try musicSound = AVAudioPlayer(contentsOf: URL (fileURLWithPath: musicFile!))
    } catch { print("ERROR PLAYING MUSIC")}

            musicSound.play() //WORKS
    //


    DispatchQueue.main.async() {
        self.performSegue(withIdentifier: "myLaunchSegue", sender: self) //WORKS
    }

我试图添加:

perform(Selector(("showNavController")), with: self, afterDelay: 3)

其中“showNavController”只是segue:

 func showNavController() {
    performSegue(withIdentifier: "myLaunchSegue", sender: nil)
}

但程序崩溃时出现错误“未捕获的异常.... ....无法识别的选择器发送到实例”

我还尝试添加一个布尔值,以防止程序继续进行,直到声音播放,但没有让它工作。有什么想法吗?

////////////////////////// 更新: 尝试罗素答案,但有一些问题。将AVAudioPlayer设置为委托,这是否意味着将它设置在类旁边:

class MyLaunchViewController: UIViewController, AVAudioPlayer { ...

另外,如何调用audioPlayerDidFinishPlaying函数?像这样:

audioPlayerDidFinishPlaying(musicSound, successfully: true)

我将发布整个代码块。让它更容易理解......

import UIKit

导入AVFoundation // FOR SOUND

class MyLaunchViewController:UIViewController,AVAudioPlayer {     var musicSound:AVAudioPlayer = AVAudioPlayer()// FOR SOUND

override func viewDidLoad() {
    super.viewDidLoad()

    //PLAY SOUND CLIP//
    let musicFile = Bundle.main.path(forResource: "fanfare", ofType: ".mp3")
    do {
        try musicSound = AVAudioPlayer(contentsOf: URL (fileURLWithPath: musicFile!))
    } catch { print("ERROR PLAYING MUSIC")}

            musicSound.play() //WORKS
    //
    audioPlayerDidFinishPlaying(musicSound, successfully: true)
}

optional func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
    DispatchQueue.main.async() {
        self.performSegue(withIdentifier: "myLaunchSegue", sender: self)
    }
}

我在课堂上写AVAudioPlayer时遇到错误(或许我误解了我应该做的事情?)。它说我有多重遗产。此外,它不希望我将新函数设置为可选,因为它仅适用于协议成员。最后,如果我纠正错误并运行程序,下一个segue会在声音播放完毕之前运行...... :(悲伤的熊猫。

1 个答案:

答案 0 :(得分:1)

您需要将LaunchScreen设为AVAudioPlayerDelegate,然后使用audioPlayerDidFinishPlaying回调。这就是你在第一个控制器中所需要的一切

import UIKit
import AVFoundation

class ViewController: UIViewController, AVAudioPlayerDelegate
{
    var musicSound: AVAudioPlayer?

    override func viewDidLoad() {
        super.viewDidLoad()
        //PLAY SOUND CLIP//
        let musicFile = Bundle.main.path(forResource: "sound", ofType: ".wav")
        do {
            try musicSound = AVAudioPlayer(contentsOf: URL (fileURLWithPath: musicFile!))
        } catch { print("ERROR PLAYING MUSIC")}

        musicSound?.delegate = self
        musicSound!.play() //WORKS
        print("Next line after play")
    }

    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
        DispatchQueue.main.async() {
            print("audioPlayerDidFinishPlaying")
            self.performSegue(withIdentifier: "myLaunchSegue", sender: self)
        }
    }
}

您可以在https://developer.apple.com/documentation/avfoundation/avaudioplayerdelegate/1389160-audioplayerdidfinishplaying

获取更多详细信息