0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

SwiftUI の Text で多言語変数展開

Last updated at Posted at 2021-07-21

はじめに

SwiftUI で多言語対応をする際、以下のように表示したいとします

英語

Apples are 1,000 yen each.

日本語

りんごは一つ1,000円です

金額が固定であれば View 側で LocalizedStringKey を指定し、 各Stringsファイルに対応する文言を書いておけば問題ありません

Swift

Text("apple")

英語

"apple" = "Apples are 1,000 yen each.";

日本語

"apple" = "りんごは一つ1,000円です";

しかし、実際には金額が変動する場合、どうすべきでしょうか

文字列

まず先に、変数が文字列の場合を見てみましょう

英語

Hello World!!

日本語

こんにちは世界!!

let target = "World" とすると、例えばこのようになります

  • Swift

    Text("hello\(target)")
    
  • 英語

    "hello%@" = "Hello %@!!";
    
  • 日本語

    "hello%@" = "こんにちは%@!!";
    

プレビュー結果(多言語プレビューモジュールを使用)

スクリーンショット 2021-07-19 18.56.31.png
スクリーンショット 2021-07-19 18.57.00.png

Strings ファイルの方で %@ としていた部分に \(target) とすることで、変数が展開されました

ただし、当然この方法では World は翻訳されません

翻訳したければ、 World の方も Strings ファイルに定義しておかねばなりません

また、 NSLocalizedString で先に翻訳してから埋め込むことになります

  • Swift

    Text("hello\(NSLocalizedString(target, comment: ""))")
    
  • 英語

    "hello%@" = "Hello %@!!";
    "world" = "World";
    
  • 日本語

    "hello%@" = "こんにちは%@!!";
    "world" = "世界";
    

ただし、 NSLocalizedString の引数に変数を渡す行為は swiftlint にエラーを出されるため、おすすめできません

TestView.swift:8:45: error: NSLocalizedString Key Violation: Static strings should be used as key/comment in NSLocalizedString in order for genstrings to work. (nslocalizedstring_key)

また、実機で動かしたときは問題ありませんが、プレビュー上は日本語の方も こんにちはWorld!! になってしまいます

以下のようにすれば、あまりキレイではありませんが、 swiftlint もエラーにならず、プレビューも機能します

  • Swift

    Text("hello") + Text(LocalizedStringKey(target)) + Text("!!")
    
  • 英語

    "hello" = "Hello ";
    "world" = "World";
    
  • 日本語

    "hello" = "こんにちは";
    "world" = "世界";
    

整数

整数の場合、文字列と同じようにしてもうまくいきません

  • Swift

    Text("price\(price)")
    
  • 英語

    "price%@" = "Apples are %@ yen each.";
    
  • 日本語

    "price%@" = "りんごは一つ%@円です";
    

これだと翻訳されないまま展開されるだけです

スクリーンショット 2021-07-19 19.29.55.png

%@ はオブジェクト(文字列含む)を指定するのに使われます

整数の場合は型の桁数に応じて指定が異なります(互換性はありません)

  • Int 、 Int64 の場合、 %lld で指定します
  • Int8 、 Int16 、 Int32 の場合、 %d を指定します

したがって、 let price = 1000 というように Int 型を使っている場合は Strings ファイルを以下のように変更します

  • 英語

    "price%lld" = "Apples are %lld yen each.";
    
  • 日本語

    "price%lld" = "りんごは一つ%lld円です";
    

スクリーンショット 2021-07-19 20.13.16.png
スクリーンショット 2021-07-19 20.13.22.png

また、もう一つの方法として、文字列にしておいてから展開する方法もあります

この方法だと %d でも %lld でも問題ありません

  • Swift

    Text("price\(String(format: "%lld", price))")
    
  • 英語

    "price%@" = "Apples are %@ yen each.";
    
  • 日本語

    "price%@" = "りんごは一つ%@円です";
    

ただし、カンマ区切りはしてくれないので、おすすめしません

スクリーンショット 2021-07-19 19.52.47.png
スクリーンショット 2021-07-19 20.11.32.png

小数

小数の場合も型の桁数に応じて指定が異なります

また、展開先( Strings ファイルの右辺)で桁数を指定します

  • CGFloat 、 Float64 、 Double の場合、 %lf を指定します
  • Float 、 Float32 の場合、 %f を指定します

実装例は以下のようになります

  • Swift

    Text("pi\(CGFloat.pi)")
    
  • 英語

    "pi%lf" = "Pi: %.2lf";
    
  • 日本語

    "pi%lf" = "円周率: %.2lf";
    

スクリーンショット 2021-07-19 19.57.26.png
スクリーンショット 2021-07-19 19.57.33.png

まとめ

Strings ファイル内で以下の指定子を使うことで翻訳しつつ変数を展開することができます

型の桁数で変わることに注意しましょう

指定子
String %@
Int %lld
Int8 %d
Int16 %d
Int32 %d
Int64 %lld
Float %f
Float32 %f
Float64 %lf
CGFloat %lf
Double %lf
0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?