Memo

メモ > 技術 > IDE: Xcode > SwiftUI+Timer

■SwiftUI+Timer
【Combine】Timerの処理をCombineを使って置き換える - Swift・iOS https://www.hfoasi8fje3.work/entry/2021/08/22/%E3%80%90Combine%E3%80%91Timer%E3%81%AE%E5%87%A6%E7%90... ContentView.swift
import SwiftUI struct ContentView: View { @ObservedObject private var viewModel = TimerModel() var body: some View { VStack { Text("\(viewModel.count)") .font(.title) .fontWeight(.bold) .padding() if viewModel.count <= 0 { Text("終了").padding() } else if viewModel.isTimerRunning { if (viewModel.count <= 3) { Text("もうすぐ終了").padding() } else { Text("カウントダウン中").padding() } } else { Text("ストップ中").padding() } Button("Start") { viewModel.startCounting() } .disabled(viewModel.isTimerRunning) Button("Stop") { viewModel.stopCounting() } .disabled(!viewModel.isTimerRunning) .padding() Button("Reset") { viewModel.resetCount() } } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() // プレビュー表示のために必要 //.environmentObject(TimerModel()) } }
TimerModel.swift
import Foundation import Combine class TimerModel: ObservableObject { @Published var count = 10 @Published var isTimerRunning = false private var cancellable: AnyCancellable? func startCounting() { isTimerRunning = true cancellable = Timer.publish(every: 1.0, on: .main, in: .common) .autoconnect() .sink { _ in if self.count <= 0 { self.stopCounting() } else { self.count -= 1 } } } func stopCounting() { isTimerRunning = false cancellable?.cancel() } func resetCount() { count = 10 } }

Advertisement