定时器结束时的SwiftUI声音正在反复播放


我创建了一个计时器。当计时器结束时,它应该播放一次完整的声音。这是一个大约5秒长的声音文件。

但当计时器结束时,声音会一遍又一遍地播放,只播放声音的前2秒。

它发生在模拟器和真实设备上。

我不知道为什么会发生这种事。我已经在谷歌上搜索voor很长一段时间了,但我找不到解决方案。

我试着把声音连接到按钮上,播放和停止功能都很好。但是,即使我尝试将"SoundManager.instance.stopSound(("放入停止按钮,当我在计时器结束时敲击它时,它仍然不会停止播放声音。

有人能告诉我我做错了什么吗?

这是我的代码:

import SwiftUI
import AVKit

class SoundManager {
static let instance = SoundManager()
var player: AVAudioPlayer?

func playSound() {
guard let url = Bundle.main.url(forResource: "Tada", withExtension: ".mp3") else {return}

do {
player = try AVAudioPlayer(contentsOf: url)
player?.play()
} catch let error {
print("Error playing sound. (error.localizedDescription)")

}
}
func stopSound() {
// Stop AVAudioPlayer
player?.stop()
}
}
struct TimerCountDown: View {
@State var countDownTimer = 30
@State var timerRunning = false
let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()

var body: some View {
VStack {
Text("(countDownTimer)")
.onReceive(timer) { _ in
if countDownTimer > 0 && timerRunning {
countDownTimer -= 1
}
else if countDownTimer < 1 {
SoundManager.instance.playSound()
}
else {
timerRunning = false

}

}
.font(.system(size: 80, weight: .bold))
.opacity(0.80)

HStack (spacing: 30) {
Button("Start") {
timerRunning = true
}
.padding()
.background(.blue)
.foregroundColor(.white)
.cornerRadius(8)

Button("Stop") {
timerRunning = false
}
.padding()
.background(.blue)
.foregroundColor(.white)
.cornerRadius(8)


Button("Reset") {
countDownTimer = 30
}
.padding()
.background(.red)
.foregroundColor(.white)
.cornerRadius(8)
}
}


}
}
struct TimerCountDown_Previews: PreviewProvider {
static var previews: some View {
TimerCountDown()
}
}

问题出在.onReceive(timer)代码中。当countDownTimer达到0时,计时器仍在每秒发布一次,因此您的代码进入第二个子句,该子句将播放结束计时器的声音。它每秒钟都这样做。只有当timerRunning时才应该这样做,当计数达到0时,应该将其设置为false

.onReceive(timer) { _ in
if timerRunning {
if countDownTimer > 0 {
countDownTimer -= 1
if countDownTimer == 0 {
timerRunning = false
SoundManager.instance.playSound()
}
}
}
}

注意:您的代码会让计时器一直处于发布状态,实际上只有在计时器运行时才需要它。请检查此答案,了解如何停止和重新启动计时器的发布。

最新更新