我在堆栈视图中有一组按钮。按下每个按钮会播放不同的声音。我有一个单独的按钮(循环按钮),按下该按钮时会调用loopButtonPressed
功能。我的目标是,当按下此循环按钮时,它将循环浏览此堆栈视图中作为按钮的子视图,并使用soundButtonPressed
功能按顺序依次播放每种声音。我看到了下面使用run()
函数实现的方法,该函数将每个连续函数设置为在给定的时间后运行。尽管这种工作方式不是一个好的解决方案,因为声音文件的长度是可变的。我在想可能有一种使用调度组来执行此操作的方法,我对此并不完全了解。如果我取消运行功能,它将仅播放堆栈视图中最后一个按钮的声音。我正在使用AVFoundation来播放wav文件。我感谢任何建议或指导,谢谢。
func run(after seconds: Int, completion: @escaping () -> Void) {
let deadline = DispatchTime.now() + .milliseconds(seconds)
DispatchQueue.main.asyncAfter(deadline: deadline) {
completion()
}
}
@objc func loopButtonPressed(_ sender: UIButton) {
var i = 1
for case let button as UIButton in self.colorBubblesStackView.subviews {
run(after: 800*i) {
self.soundButtonPressed(sender: button)
}
i += 1
}
}
我的soundButtonPressed函数只是一个switch语句,其中每种情况都使用正确的声音文件名调用函数playSound()
。这是playSound函数:
func playSound(_ soundFileName: String) {
guard let url = Bundle.main.url(forResource: soundFileName, withExtension: "wav") else { return }
do {
try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default)
try AVAudioSession.sharedInstance().setActive(true)
player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.wav.rawValue)
guard let player = player else { return }
player.play()
} catch let error {
print(error.localizedDescription)
}
}
func playSound(name: String ) {
guard let url = Bundle.main.url(forResource: name, withExtension: "mp3") else {
print("url not found")
return
}
do {
/// this codes for making this app ready to takeover the device audio
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
try AVAudioSession.sharedInstance().setActive(true)
/// change fileTypeHint according to the type of your audio file (you can omit this)
player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileTypeMPEGLayer3)
player?.delegate = self
// no need for prepareToPlay because prepareToPlay is happen automatically when calling play()
player!.play()
} catch let error as NSError {
print("error: \(error.localizedDescription)")
}
}
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
print("finished")//It is working now! printed "finished"!
}
确认协议
class ViewController: UIViewController,AVAudioPlayerDelegate {
并且除了循环之外,还为每个按钮添加一个标签,并从第一个标签sat 100开始。然后,当为播放器获得的回叫结束播放后,播放带有新icremented标签的下一个文件,说101