Quantcast
Channel: Recent Questions - Stack Overflow
Viewing all articles
Browse latest Browse all 12141

Timers won't stop playing sound

$
0
0

Im trying to create an app with playing sound and 4 timers to use If user want to. When timers are finished playing should stop. I got really stuck with this timers here and they are counting down but they don't stop and reset after user stop playback. Also they won't stop the sound if they finished :) their are just counting down..Could you see what im I doing wrong?Thanks

My TimerViewModel:

import Foundationimport Combineclass TimerViewModel: ObservableObject {    @Published var remainingTime: Int = 0        @Published var totalDuration: Int = 0    @Published var timerActive: Bool = false    private var timer: AnyCancellable?    private var audioPlayerViewModel: AudioPlayerViewModel    init(audioPlayerViewModel: AudioPlayerViewModel) {        self.audioPlayerViewModel = audioPlayerViewModel    }    func startTimer(duration: Int) {        remainingTime = duration        totalDuration = duration        timerActive = true        timer = Timer.publish(every: 1, on: .main, in: .common)            .autoconnect()            .sink { [weak self] _ in                self?.tick()            }    }    private func tick() {        if remainingTime > 0 {            remainingTime -= 1        } else {            stopTimer()            stopPlayback()        }    }    func stopTimer() {        timerActive = false        timer?.cancel()        timer = nil    }    func resetTimer() {            stopTimer()            remainingTime = 0        }    private func stopPlayback() {        audioPlayerViewModel.audioPlayer?.pause()     }}

My PlayerViewModel:

import SwiftUIimport AVFoundationclass AudioPlayerViewModel: ObservableObject {    var timerViewModel: TimerViewModel?    var audioPlayer: AVAudioPlayer?    @Published var isPlaying = false    init() {        if let asset = NSDataAsset(name: "thesound") {            do {                self.audioPlayer = try AVAudioPlayer(data: asset.data, fileTypeHint: "mp3")            } catch {                print("AVAudioPlayer could not be instantiated.", error)            }        } else {            print("Audio file could not be found.")        }    }    func playOrPause() {        guard let player = audioPlayer else { return }        if player.isPlaying {                    player.pause()                    isPlaying = false                    timerViewModel?.stopTimer()            timerViewModel?.resetTimer()                } else {                    player.play()                    isPlaying = true                }    }}

TimersView:

import SwiftUIstruct TimersView: View {    @StateObject private var audioPlayerViewModel = AudioPlayerViewModel()    @ObservedObject var viewModel: TimerViewModel    var body: some View {        VStack {            HStack(spacing: 60) {                ForEach([15, 30, 45, 60] as? [Int] ?? [], id: \.self) { minute in                    Button(action: {                        viewModel.startTimer(duration: minute * 60)                    }) {                        if minute == 60 {                            Text("1 h")                                .foregroundStyle(.white)                                .whiteTextWithCircularBorder()// Jeśli minuta wynosi 60, wyświetl "1 h"                        } else {                            Text("\(minute)")                                .foregroundStyle(.white)                                .whiteTextWithCircularBorder()// W przeciwnym razie wyświetl normalną liczbę minut                        }                    }                }            }        }    }}extension Text {    func whiteTextWithCircularBorder() -> some View {        self            .overlay(                Circle()                    .stroke(Color.white, lineWidth: 1)                    .frame(width: 50, height: 50)            )    }}

ContentView:

import SwiftUIimport AVFoundationstruct ContentView: View {    @StateObject var audioPlayerViewModel = AudioPlayerViewModel()    @StateObject var timerViewModel = TimerViewModel(audioPlayerViewModel: AudioPlayerViewModel())    var body: some View {        ZStack {            Color.black                .ignoresSafeArea()            VStack {                Spacer()               Spacer()                Button(action: {                    audioPlayerViewModel.playOrPause()                }) {                    Image("Icon-inside")                        .resizable()                        .scaledToFit()                        .frame(width: 100, height: 100)                }                Text(audioPlayerViewModel.isPlaying ? "" :  "Push it" )                     .font(.subheadline)                    .foregroundStyle(.white)                Spacer()                if audioPlayerViewModel.isPlaying {                TimersView(viewModel: timerViewModel)                         Text("\(timerViewModel.remainingTime / 60) min")                        .foregroundStyle(.white)                        .padding(.top, 50)                        .padding(.bottom, 50)                }            }        }    }}
  1. I need timers to stop playing sound after countdown is finished.
  2. I need to reset and stop timers when user manually turn of sound by pressing the play/pause button

Viewing all articles
Browse latest Browse all 12141

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>