📅

[SwiftUI]FormatStyleを用いてText表示する

に公開

SwiftUIのTextにiOS15以降から新しいInitializerがあるのを改めて調べたのでメモ。

DateFormatter

DateTextに表示したい場合、DateFormatterを利用していました。
定義したformatterでDateからStringへ変換しています。

let formatter = DateFormatter()
formatter.dateStyle = .short
formatter.timeStyle = .none

Text(dateFormatter.string(from: Date.now)) // 10/17/2023

が、もっと簡潔に記述できる方法がありました。

Text(Date.now, format: Date.FormatStyle(date: .numeric, time: .omitted))
// 10/17/2023

formatを指定することでString以外を受け入れられる用になりました。

新旧Styleの違い

これまで利用していたStyleはenumで定義されていました。

extension DateFormatter {

  public enum Style : UInt, @unchecked Sendable {

    case none = 0

    case short = 1

    case medium = 2

    case long = 3

    case full = 4
  }
}

一方で、新しいStyleDateStyleTimeStyleに区別され、スタティックプロパティが定義されています。
また、細かな挙動の違いをより的確な名前で表現されていることが伺えます。

@available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)
extension Date.FormatStyle {

    /// Predefined date styles varied in lengths or the components included. The exact format depends on the locale.
    public struct DateStyle : Codable, Hashable, Sendable {

        /// Excludes the date part.
        public static let omitted: Date.FormatStyle.DateStyle

        /// Shows date components in their numeric form. For example, "10/21/2015".
        public static let numeric: Date.FormatStyle.DateStyle

        /// Shows date components in their abbreviated form if possible. For example, "Oct 21, 2015".
        public static let abbreviated: Date.FormatStyle.DateStyle

        /// Shows date components in their long form if possible. For example, "October 21, 2015".
        public static let long: Date.FormatStyle.DateStyle

        /// Shows the complete day. For example, "Wednesday, October 21, 2015".
        public static let complete: Date.FormatStyle.DateStyle

        ...
    }

    /// Predefined time styles varied in lengths or the components included. The exact format depends on the locale.
    public struct TimeStyle : Codable, Hashable, Sendable {

        /// Excludes the time part.
        public static let omitted: Date.FormatStyle.TimeStyle

        /// For example, `04:29 PM`, `16:29`.
        public static let shortened: Date.FormatStyle.TimeStyle

        /// For example, `4:29:24 PM`, `16:29:24`.
        public static let standard: Date.FormatStyle.TimeStyle

        /// For example, `4:29:24 PM PDT`, `16:29:24 GMT`.
        public static let complete: Date.FormatStyle.TimeStyle

        ...
    }
}

その他のFormatStyle

Dateに限らずいろんな型に合わせて、柔軟な表現ができるようになりました。
例はIntIntegerFormatStyleを用いて値段を表現しています。

Text(123456, format: IntegerFormatStyle.Currency.currency(code: "JPY")) // ¥123,456
Text(123456, format: IntegerFormatStyle.Currency.currency(code: "USD")) // $123,456.00

こちらの記事でわかりやすく一覧化されているのでご覧ください。
https://qiita.com/hyuga_amazia/items/e69e5b4e8c65fcd013a9#integerformatstyle

おまけ

単にDateからformattedメソッドでStringを返すこともできますね。

Text(Date.now.formatted(date: .numeric, time: .omitted))

どなたかの参考になれば幸いです。
ありがとうございました。

参考

https://developer.apple.com/documentation/foundation/formatstyle
https://developer.apple.com/documentation/swiftui/text/init(_:format:)

GitHubで編集を提案

Discussion