SwiftUI のCanvas Preview で多言語対応する

1 min read読了の目安(約1500字

SwiftUI のCanvas Preview を使うと、端末の種類や言語・地域設定ごとにUI の表示を確認できて開発が捗ります。
今回はPreview におけるロケールの判定について調べたのでメモします。

事前準備

Xcode で次の作業を実施済みの前提とします。

  • Localizations の追加
  • Localizable.strings の追加・記述

SwiftUI のCanvas で言語別にPreview を表示する

struct YourVieww_Previews: PreviewProvider {
    static var previews: some View {
        ForEach(["en_US", "ja_JP"], id: \.self) { id in
            YourView()
                .environment(\.locale, .init(identifier: id))
        }
    }
}

このように書くと、プレビューがen_USja_JP とでそれぞれ表示されます。

Text の多言語対応

Text については、LocalizedStringKey を渡すことでPreview での多言語表示対応が可能です。

https://zenn.dev/ariiyu/articles/d7b3cfefec057f

Preview 時にロケールが判定できない問題

Text にキーを渡す場合と異なり、View の処理で任意のロケールの判定をしたいことがあります。

var body: some View { 
  if isJA(locale: locale) {
    Rectangle()
      .background(Color.red)
  }

以下はSwiftUI が登場する前から使っていたようなコードです。
これらのコードでは、アプリ実行時には意図通りに日本語環境の判定がされますが、SwiftUI のCanvas Preview では判定がされません。

func isJA() -> Bool {
    let currentLanguage = Locale.preferredLanguages[0]
    return currentLanguage.hasPrefix("ja")
}
func isJA() -> Bool {
    return Locale.current.identifier.hasPrefix("ja")
}

Preview 時にロケールを判定する

@Environment(\.locale) を使うことで、Canvas Preview でも日本語環境を判定してくれるようになりました。

struct YourView: View {
    @Environment(\.locale) var locale
func isJA(locale: Locale) -> Bool {
    return locale.identifier.hasPrefix("ja")
}