繁体   English   中英

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

[英]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

试试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()
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM