タイマー付きカウントダウン
Foundation、SwiftUI、Combineフレームワークと組み合わせることで、ユーザーに少しプレッシャーを与えるタイマーをアプリケーションに追加することができます。最も単純な実装は少しの努力でこれを行いますが、解決しなければならないバグがあります。
タイマーは1秒に1回起動し、timeRemaining プロパティはタイマーが起動するたびに 1 減算されます。
ContentViewに以下の2つのプロパティを追加します:
@State private var timeRemaining = 100
let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
メインスレッドにタイマーが作成され、起動されます。
もちろん、日付計算の助けを借りてカウントダウンすることも可能ですが、ここではその必要はまったくありません。
ContentViewの一番外側のZStackにonReceive()モディファイアを追加します。
.onReceive(timer) { time in
if self.timeRemaining > 0 {
self.timeRemaining -= 1
}
}
ヒント: 負の値にならないようにテスト条件を追加します。
タイマーのカウントダウンは100から0までですが、数字を表示する必要があります。
Text("Time: \(timeRemaining)")
.font(.largeTitle)
.foregroundColor(.white)
.padding(.horizontal, 20)
.padding(.vertical, 5)
.background(
Capsule()
.fill(Color.black)
.opacity(0.75)
)
適切な場所に配置すれば、レイアウトコードは次のようになるはずです:
ZStack {
Image("background")
.resizable()
.scaledToFill()
.edgesIgnoringSafeArea(.all)
VStack {
Text("Time: \(timeRemaining)")
.font(.largeTitle)
.foregroundColor(.white)
.padding(.horizontal, 20)
.padding(.vertical, 5)
.background(
Capsule()
.fill(Color.black)
.opacity(0.75)
)
ZStack {
アプリをもう一度実行してみてください。しかし、ここに小さな問題があります:
- 現在時刻の表示
- ホーム画面に戻るにはCmd+Hをクリックします。
- 10秒待つ
- アプリアイコンをタップしてアプリに戻ります
- タイマーは時間を表示するのですか?
つまり、タイマーはバックグラウンドで数秒間作動し、アプリが戻るまで一時停止します。
アプリがバックグラウンドまたはフォアグラウンドになった場合、それに応じてタイマーを一時停止または再開します。
まず、アプリケーションが現在アクティブかどうかの状態を保存するために、このプロパティを追加します:
@State private var isActive = true
UIApplication.willResignActiveNotification UIApplication.willEnterForegroundNotification 次に、アプリケーションのisActiveを維持するために、さらに2つのonReceive()モディファイアを追加する必要があります。 このために、以下のようにandの通知をキャプチャすることができます:
.onReceive(NotificationCenter.default.publisher(for: UIApplication.willResignActiveNotification)) { _ in
self.isActive = false
}
.onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)) { _ in
self.isActive = true
}
最後に、onReceive(timer)関数を修正して、isActiveの時にカウントダウンしないようにします:
.onReceive(timer) { time in
guard self.isActive else { return }
if self.timeRemaining > 0 {
self.timeRemaining -= 1
}
}
この小さな修正により、アプリがバックグラウンドに移行すると、カウントダウンは自動的に一時停止します。





