如何依次在for循环中运行函数

问题描述 投票:0回答:2

我在堆栈视图中有一组按钮。按下每个按钮会播放不同的声音。我有一个单独的按钮(循环按钮),按下该按钮时会调用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)
        }
    }
ios swift avfoundation synchronous dispatchgroup
2个回答
0
投票
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


0
投票

尝试AVQueuePlayer

用于依次播放许多项目的播放器。

AVQueuePlayer
© www.soinside.com 2019 - 2024. All rights reserved.