WWDC Quick Look 💓 By SwiftGGTeam
Get it right (to left)

Get it right (to left)

元の動画を見る

ハイライト

アラビア語は、Apple プラットフォームで最も使用されている言語のトップ 10 の 1 つです。 RTL (右から左) 言語はテキストの方向を反転するだけではなく、ツールバーからサイドバー、アイコンから数値表示に至るまで、UI レイアウト全体に影響します。


主要内容

アプリを英語、フランス語、日本語、中国語にローカライズしている可能性があります。次に、アラビア語やヘブライ語をサポートする場合、問題は異なります。テキストが右から左に配置され、英語の製品名や番号が段落に挟まれる可能性があります。

(00:22) リッチ・ギラムは冒頭で、アラビア語が Apple プラットフォームで最も使用されている言語のトップ 10 の 1 つであると述べました。 Apple プラットフォームは、15 の右から左に記述する言語のフォントとキーボードのサポートも提供します。

この方向の変化はインターフェース全体に伝わります。 (02:17) Numbers ヘルプ ページのヘブライ語版では、テキストが右揃えで、表と図の位置が逆になっています。 Safari ウィンドウに配置すると、ツールバーも右から左に配置されます。システム全体に配置すると、メニュー バー、ドック、サイドバー、タブ バーがすべて反転します。

幸いなことに、システムはほとんどの作業をすでに行っています。 (03:21) CoreText は双方向テキストを処理し、Apple の UI フレームワークはデフォルトで自然な書き込み方向と自然な配置を設定し、標準コントロールは自動的に反転します。開発者は、どのアイコンをミラーリングする必要があるか、どのコントロールが絶対方向を維持する必要があるか、どの番号をユーザーの地域や好みに応じて表示する必要があるかなど、エッジケースに対処する必要があります。


詳細

テキストはまず処理のためにシステムに渡されます。

(04:21) 双方向テキストは右から左へ記述する言語でよく発生します。ヘブライ語の文には、Pages、Numbers、Keynote などの英語の単語を含めることができます。英語は依然として左から右に読まれ、段落全体の断片の順序は右から左です。

(05:18) ほとんどのテキスト コントロールでは、向きを手動で設定する必要はありません。 CoreText は同じ行上で文字を異なる方向に配置し、UIKit、AppKit、および SwiftUI のテキスト コントロールは自然な書き込み方向と自然な配置を使用します。アラビア語またはヘブライ語の UI では、テキスト コントロールは右から左に書かれ、デフォルトで右揃えになります。

このルールの実際的な意味は非常に単純です。通常のテキスト、ボタン タイトル、フォーム入力ボックスについてはシステムのデフォルトを維持します。デフォルトの動作のオーバーライドは、絶対的な方向を表現する場合にのみ考慮されます。

アイコンは「方向」と「意味」を区別する必要があります

(07:50) カスタム イメージの RTL 動作は、Xcode イメージセット エディターで設定されます。画像が言語に応じて変化しない場合は、「固定」を選択します。アルゴリズムによるミラーリングが可能な場合は「ミラー」を選択します。単純なミラーリングが不可能な場合は「両方」を選択し、LTR と RTL にそれぞれイメージを提供します。

(09:06) SF シンボルを使用する場合、多くのローカリゼーションはシステムによってすでに処理されています。読み取り方向に応じて変更する必要があるシンボルは自動的に反転されます。疑問符などの記号には、アラビア語にローカライズされたバージョンもあります。

(10:17) 矢印は名前によって異なります。arrow.backward.circleこれは「戻る」を意味し、RTL では反転されます。arrow.left.circle絶対左側を表し、RTL では反転されません。

Label("Preview", systemImage: "arrowtriangle.forward.fill")
Label("Left", systemImage: "arrow.left")
Label("Right", systemImage: "arrow.right")

キーポイント:

  • arrowtriangle.forward.fill使用forward読み出し方向の「前方」を表す、RTLで反転します。 -arrow.left絶対方向を使用するleft、常に左を指します。 -arrow.right絶対方向を使用するright、常に右を指します。

環境を使用して SwiftUI のコントロールの方向を制御する

(12:55) 標準コントロールは、UI の方向に合わせて自動的に反転します。ボタンにテキストとアイコンがある場合、SwiftUI はパスします。LabelStyleアイコンがテキストのどちら側にあるのかを制御し、必要に応じて環境値を使用して特定のビューのレイアウト方向を修正します。

struct ContentView: View {
    var body: some View {
    VStack(alignment: .leading) {
        Button(action: {}) {
            Label("Preview", systemImage: "arrowtriangle.forward.fill")
        }.labelStyle(IconOnRightLabelStyle())
            
            HStack() {
                Button(action: {}) {
                    Label("Left", systemImage: "arrow.left")
                }.labelStyle(TitleAndIconLabelStyle())

                Button(action: {}) {
                    Label("Right", systemImage: "arrow.right")
                }.labelStyle(IconOnRightLabelStyle())
            }.environment(\.layoutDirection, .leftToRight)
        }.padding()
    }
}

キーポイント:

  • VStack(alignment: .leading)先頭を使用し、左側を書かないでください。 -arrowtriangle.forward.fill読書方向に対する進行状況を表現するためにプレビューに使用されます。 -TitleAndIconLabelStyle()左ボタンアイコンを読み方向でタイトルの前に配置します。 -IconOnRightLabelStyle()これはカスタム スタイルなので、プレビュー アイコンと右アイコンがタイトルの後ろにあります。 -.environment(\.layoutDirection, .leftToRight)Left と Right が含まれる場合にのみ追加されますHStackをオンにすると、2 つのボタンが左から右に配置されたままになります。
  • プレビューはこの環境オーバーライドを継承しないため、RTL UI のシステム ルールによって反転されます。

(14:22) カスタム ラベル スタイルの実装は小規模です。タイトルとアイコンを一定の順序で配置するだけですHStack

struct IconOnRightLabelStyle : LabelStyle {
    func makeBody(configuration: Configuration) -> some View {
        HStack {
            configuration.title
            configuration.icon
        }
    }
}

キーポイント:

  • IconOnRightLabelStyle成し遂げるLabelStyle
  • makeBody(configuration:)システムが提供するタイトルとアイコンを受け取ります。 -HStackサブビューの順序によって表示順序が決まります。 -configuration.titleタイトルを最初に表示して、最初に入力します。 -configuration.icon入れると奥にアイコンが表示されます。

(16:32) AppKit と UIKit は同じ概念を持っています。 Interface Builder では、Leading、Trailing、Left、Right が使用されます。ボタンは AppKit コードで使用されます。imagePosition; UIKitはボタン構成ですimagePlacement。先頭と末尾は UI の方向に応じて変化し、左と右は絶対的な方向を維持します。

セグメント化されたコントロールとレイアウトは、用途に応じて反転する必要があります。

(18:58) テキスト スタイル ボタン 太字、斜体、下線などのセグメント化されたコントロールは、UI の方向に応じて反転できます。テキスト配置ボタンは絶対的な左、中央、右を表し、順序は変更されない必要があります。

struct ContentView: View {
    var body: some View {
        VStack(alignment: .leading) {
            Picker(selection: $textStyle, label: Text("Text Style")) {
                Text("B").tag(TextStyle.bold)
                Text("I").tag(TextStyle.italic)
                Text("U").tag(TextStyle.underline)
                Text("S").tag(TextStyle.strikethrough)
            }.pickerStyle(.segmented)

            Picker(selection: $alignment, label: Text("Alignment")) {
                Image(systemName: "text.alignleft").tag(TextAlignment.left)
                Image(systemName: "text.aligncenter").tag(TextAlignment.center)
                Image(systemName: "text.alignright").tag(TextAlignment.right)
           }.pickerStyle(.segmented)
             .environment(\.layoutDirection, .leftToRight)
        }
    }
}

キーポイント:

  • 初めPickerデフォルトの RTL 動作を維持して、テキスト スタイルを表します。
  • 2番目Pickerテキストの配置を示し、アイコンには絶対的な方向の意味があります。 -text.alignlefttext.aligncentertext.alignright左固定、中央固定、右固定に対応。 -.environment(\.layoutDirection, .leftToRight)配置コントロールでのみ機能し、RTL UI でも左、中央、右に表示されます。

(19:16) UIKit は使用しますsemanticContentAttributeエクスプレス制御セマンティクス。デフォルトUnspecifiedUI の方向に合わせて反転します。Spatial位置合わせ制御に適した空間方向制御を表します。左から右または右から左に強制することもできます。 AppKit で NSControl のレイアウトとミラー設定を使用するか、コードで設定しますuserInterfaceLayoutDirection

複数行のラベルはテキスト ボックス内で揃える必要があります

(22:38) フォーム内の単一行ラベルはテキスト オブジェクト自体と揃えるだけでよく、複数行ラベルはテキスト オブジェクト内の各行と揃える必要があります。 SwiftUIを使用するmultilineTextAlignmentこの問題に対処してください。

var body: some View {
   Form {
        TextField("Password:", text: $password)
        TextField("Verify:", text: $verifyPassword)
        TextField("Password Hint:\n(Recommended)", text: $passwordHint)
            .multilineTextAlignment(.trailing)
    }.padding()
}

キーポイント:

  • Formフォームのラベルと入力ボックスの全体的なレイアウトを担当します。
  • 最初の 2 つTextFieldは単一行のラベルであり、システムはそれらの境界ボックスを直接位置合わせできます。
  • 三番目TextFieldタグには改行が含まれており、テキスト内の各行を処理する必要があります。 -.multilineTextAlignment(.trailing)読み取り方向の尾側に揃えるには、トレーリングを使用します。
  • RTL UI では、トレーリングの物理的な方向が逆になります。

自動レイアウトでは先頭と末尾が優先されます。

(26:32) 標準ビュー、ナビゲーション コントローラー、ページ コントローラー、テーブル、コレクション ビューはすべて、UI の方向に従ってレイアウトとスクロール方向を自動的に調整します。手書きレイアウトの場合は、制約で「読む方向」も表現し、左右の固定を少なくします。

myView.leadingAnchor.constraint(equalTo: mySuperView.leadingAnchor, constant:16)

キーポイント:

  • leadingAnchor読み取りを開始する面を示します。
  • LTR UI では、行頭は左になります。
  • RTL UI では、先頭が右側になります。 -constant:16余白は維持され、方向は UI 言語に基づいた自動レイアウトによって処理されます。

(26:53) 絶対的な左右を固定したい場合は、Interface Builder の制約メニューで [言語の方向を尊重する] をオフにして、先頭/末尾を左/右にすることができます。しかしセッション氏は、この状況はまれな例外として扱うことを推奨している。

数値はローカリゼーションと書式設定を通じて生成する必要があります

(28:02) アラビア語とヒンディー語はどちらも非ラテン数字を使用する場合があります。アラビア語でアラビア語とインド語の数字が使用されるかどうかも、国とユーザーの好みによって異なります。数値を文字列に変換し、それらを連結してラテン数字を固定します。

myLabel.string = String(localized: "There are \(peopleInChat) people in this chat.",
                        comment: "Label indicating number of chat participants")

Text("There are \(peopleInChat) people in this chat.",
     comment: "Label indicating number of chat participants")

キーポイント:

  • String(localized:)翻訳可能な文字列はアプリバンドルから検索されます。 -\(peopleInChat)補間された値は、ユーザーのロケールと設定に従って数値をレンダリングします。 -comment翻訳者に文脈を説明します。
  • SwiftUITextイニシャライザは補間の数値も正しく処理します。

(30:12) コンパイル時に数値がわかっている場合でも、同じアラビア語ローカリゼーションがユーザーの数値設定に従うことができるように、実行時補間をお勧めします。

myLabel.string = String(localized: "This application supports \(3) file formats.",
                        comment: "Label showing number of supported file formats
                        (number is always 3)")

キーポイント:

  • \(3)固定数値もローカライズされた書式設定プロセスに任せます。
  • アラビア語またはヒンディー語の翻訳のコピーは 1 つだけ保持し、デジタル システムでローカリゼーション ファイルをコピーする必要はありません。
  • コメントでは、翻訳者がビジネス上の意味を誤解しないように、この数字は常に 3 であると明確に述べられています。

(31:41) パーセント記号、通貨記号、単位の位置を手書きでつなぎ合わせることができません。パーセント記号の位置は、アラビア語、ヘブライ語、トルコ語で異なる場合があり、アラビア語とインド語の数字でも異なるパーセント記号文字が使用される場合があります。

myLabel.stringValue = String(localized: "\(percentComplete.formatted(.percent)) complete")

キーポイント:

  • percentComplete.formatted(.percent)フォーマッタにパーセント記号、数値、記号の配置を決定させます。 -String(localized:)フォーマットされた結果をローカライズされた文に挿入します。
  • ランタイム補間により方向マーカーが追加され、数値と周囲の RTL テキストが相互に干渉するのを防ぎます。

擬似言語を使用した RTL のテスト

(32:21) RTL のテストでは、最初にアラビア語またはヘブライ語の翻訳を完了する必要はありません。 Xcode スキーム エディターのオプションで、アプリ言語を Right-to-Left Pseudolang に設定します。アプリには引き続き開発言語が表示されますが、インターフェイスは RTL に切り替わります。

このステップは、定期的なテスト プロセスに組み込むのに適しています。ハードコーディングされた左/右、不正なミラー アイコン、不正な制御順序、デジタル フォーマットのスプライシングなどの問題がすぐに明らかになります。


重要ポイント

1. 既存のフォームに対して RTL チェックを実行します。

  • 何をすべきか: 右から左への擬似言語でログイン、支払い、データ編集、その他のフォームを実行し、ラベル、入力ボックス、複数行のプロンプト、およびボタン シーケンスを確認します。
  • 実行する価値がある理由: セッションでは、標準コントロールは自動的に反転しますが、複数行のラベルと絶対方向コントロールは依然として手動の判断が必要であると明確に述べています。
  • 開始方法: まず、Xcode スキーム エディターで RTL 擬似言語を選択し、次に複数行ラベルを追加します。.multilineTextAlignment(.trailing)、方向が固定されている必要があるコントロールを追加しますlayoutDirectionカバー。

2. 全方向の SF シンボルを監査する

  • 対処方法: アプリケーション内の矢印、再生、戻る、展開、インデントなどの記号を列挙し、それらが読み取り方向を表しているのか、絶対方向を表しているのかを判断します。
  • 実行する価値がある理由:forward/backwardRTLで反転します、left/right間違った名前を選択すると、誤ったナビゲーションや空間操作の意味が生じる可能性があるため、固定してください。
  • 開始方法: 代わりに「次へ/戻る」を使用してくださいforwardbackwardシリーズ、「左揃え/右へ移動」を維持します。leftrightシリーズ。

3. ユーザーに表示される文字列内の数字のスプライシングを削除する

  • やるべきこと: 検索+スプライシング、String(format:)、手書き%または通貨記号の UI 文字列。
  • 実行する価値がある理由: アラビア語、ヒンディー語、およびユーザーの数値設定により、数字が変更されます。パーセント記号と通貨記号の位置も言語によって異なります。
  • 開始方法: ユーザーに表示される文字列を移行しますString(localized:)またはSwiftUIText補間。パーセンテージを次のように変更します。value.formatted(.percent)

4. カスタムピクチャの方向設定を完了します

  • 何をすべきか: アセット カタログで方向性のあるカスタム イメージを確認し、それらが固定、ミラー、または両方であるかどうかを判断します。
  • 実行する価値がある理由: SF シンボルは多くのローカライズされたアイコンを自動的に処理できますが、カスタム イメージはイメージセット エディターで方向の動作を指定する必要があります。
  • 開始方法: 単純にミラーリングできる画像の場合は「ミラー」を選択します。テキスト、影、または複数の方向要素を含む画像の場合は「両方」を選択し、LTR/RTL リソースの両方を提供します。

関連セッション

コメント

GitHub Issues · utterances