今回作成するアプリ

タイマーアプリなどを作る際に、デフォルトでは1, 2, 3秒など秒単位までしか表示することができません。

しかし、もっと細かいミリ秒(mm)で表示したい場合もあると思います。

そこで、今回はSwiftUIでミリ秒単位で時間を表示する方法をご紹介します。

実装

コード

import SwiftUI

struct ContentView: View {
    @State private var timeInterval: TimeInterval = 0
    
    private let formatter = TimerFormatter()
    private let timer = Timer.publish(every: 0.01, on: .main, in: .common).autoconnect()
    
    var body: some View {
        Text(NSNumber(value: timeInterval), formatter: formatter)
            .font(.system(size: 50, weight: .light, design: .monospaced))
            .onReceive(timer) { _ in timeInterval += 0.01 }
            .padding()
    }
}

class TimerFormatter: Formatter {
    let componentFormatter: DateComponentsFormatter = {
        let formatter = DateComponentsFormatter()
        formatter.allowedUnits = [.hour, .minute, .second]
        formatter.zeroFormattingBehavior = .pad
        return formatter
    }()

    override func string(for obj: Any?) -> String? {
        guard let time = obj as? TimeInterval else { return nil }
        guard let formattedString = componentFormatter.string(from: time) else { return nil }
        
        let hunredths = Int((time.truncatingRemainder(dividingBy: 1)) * 100)
        let decimalSperator = Locale.current.decimalSeparator ?? "."
        return String(format: "%@%@%0.2d", formattedString, decimalSperator, hunredths)
    }
}

解説

ContentViewは、Viewプロトコルに準拠する構造体で、タイマーの時間間隔を追跡するために、@StateプロパティtimeIntervalを使用しています。このプロパティは、0で初期化されます。

Textビューは、時間間隔を表示するために使用されます。このTextビューには、NSNumberFormatterが渡されます。NSNumberは、timeIntervalプロパティの値を表し、Formatterは、TimerFormatterオブジェクトが割り当てられています。

TimerFormatterは、Formatterクラスを継承するカスタムフォーマッタークラスです。このクラスは、string(for:)メソッドを実装しています。このメソッドは、タイマーの時間間隔を受け取り、それをフォーマットして、時、分、秒、および100分の1秒の形式で返します。

ContentViewには、timerという名前のTimerがあります。このtimerは、Timer.publish(every:on:in:)メソッドを使用して、0.01秒ごとに実行されるTimerオブジェクトを作成します。autoconnect()メソッドは、Timerオブジェクトを自動的に接続します。このタイマーは、.onReceive(_:)メソッドを使用して、時間間隔を更新し、ビューを再描画します。

最後に、ビューには、padding()メソッドが追加されています。これにより、テキストがビューの端から離れるように設定されます。

動作

環境

macOS Ventura 13.0.1

Xcode 14.2

iOS 16.2

Simulater iPhone 14 Pro Max

アイキャッチ画像 出典: App.com