メモ > 技術 > 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
}
}