[英]How to run a function in a for loop sequentially
我在堆栈视图中有一组按钮。 每个按钮按下时都会播放不同的声音。 我有一个单独的按钮(循环按钮),按下时会调用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()
。 这是 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 开始。 然后当玩家获得的回调完成播放播放下一个带有新标签的文件时说 101
曾经按顺序播放多个项目的播放器。
@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()
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.