如何在for循环中按顺序运行函数



我在堆栈视图中有一组按钮。按下每个按钮都会播放不同的声音。我有一个单独的按钮(循环按钮(,按下时会调用loopButtonPressed函数。我的目标是,当按下这个循环按钮时,它将循环通过这个堆栈视图中的按钮子视图,并使用soundButtonPressed函数按顺序播放每个声音。我在下面看到了一个使用run()函数实现的方法,该函数将每个连续函数设置为在给定时间后运行。虽然这类工作,但它不是一个很好的解决方案,因为声音文件的长度各不相同。我想可能有一种方法可以使用调度组来实现这一点,但我并不完全理解。如果我去掉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()。这是播放声音功能:

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 {

而不是循环添加每个按钮一个标签并从第一个标签开始100。然后,当为玩家获得的回叫完成播放时,播放带有新icremented标签的下一个文件,比如101

尝试AVQueuePlayer

一种玩家,用于按顺序播放多个项目。

@objc func loopButtonPressed(_ sender: UIButton) {
let allUrls = allSongs.compactMap { Bundle.main.url(forResource: $0, withExtension: "wav") }
let items = allUrls.map { AVPlayerItem(url: $0) }
let queuePlayer = AVQueuePlayer(items: items)
queuePlayer.play()
}

相关内容

  • 没有找到相关文章

最新更新