30

一部のアプリでは、アプリを再起動せずにアプリ内で言語を内部的に変更できるようです。それらがどのように実装されているのか疑問に思っています。

たとえば、を使用している場合、実行時に初期化されていないときにNSLocalizedString言語を設定できることはわかっていますが、初期化されると(特にビューコントローラーが作成されると)、変更は次の再起動まで有効になりませんmain.mAppDelegate

[[NSUserDefaults standardUserDefaults] 
    setObject:[NSMutableArray arrayWithObjects:language, nil] 
    forKey:@"AppleLanguages"];

アプリを再起動せずにこれらの動的な言語変更を行う方法を知っている人はいますか?

4

6 に答える 6

6

ここでは、他のアプローチ、特に通知ベースのアプローチについていくつかの議論があります。

iOS:アプリを再起動せずにプログラムでアプリの言語を変更する方法は?

私の見解では、実際には 3 つのタスクがあります。(1) nib から自動的にロードされたリソースの再ローカライズ。(たとえば、ペン先から別のカスタム UIView を動的にインスタンス化する場合、「古い」言語文字列と設定 (画像、テキスト方向) は引き続き読み込まれます) (2) 現在画面に表示されている文字列の再ローカリゼーション。(3) 開発者 (あなた) がプログラム コードに挿入した文字列の再ローカリゼーション。

(3)から始めましょう。定義を探すと、NSLocalizedString がマクロであることがわかります。したがって、既存のコードをあまり変更したくない場合は、新しいヘッダー ファイルを作成することで (3) の問題を解決できる可能性があります。そのヘッダー ファイルで、適切な場所からローカライズされた文字列を#undef再度#define NSLocalizedString選択します。iOS のデフォルトではなく、何らかのグローバル変数 (アプリ デリゲート ivar など) で追跡している場所です。NSLocalizedString を再定義したくないが独自の代替を作成している#undef NSLocalizedString場合、将来の開発者が置き換えたマクロの代わりに誤ってそれを呼び出してほしくない場合は、おそらくそうする必要があります。理想的なソリューションではありませんが、おそらく最も実用的なソリューションです。

(1)については、Interface Builder でローカライズを行っておらず、viewDidLoad などで動的にローカライズする場合は問題ありません。説明したのと同じ動作 (つまり、変更された NSLocalizedString など) を使用できます。それ以外の場合は、(a) 上記のリンクで説明されているように通知システムを実装する (複雑)、または (b) ローカライズを IB から viewDidLoad に移行することを検討する、または (c)initWithNibName:古い言語リソースでロードされたオブジェクトをオーバーライドして交換することを試みることができます。 、新しい言語リソースがロードされたもの。これは、このディスカッションの一番下で Mohamed が言及したアプローチでした: http://learning-ios.blogspot.ca/2011/04/advance-localization-in-ios-apps.html. 彼はそれが問題を引き起こすと主張しています (viewDidLoad は呼び出されません)。うまくいかなくても、試してみると何かうまくいくことがわかるかもしれません。

最後に、(2) はおそらく最も簡単なタスクです。現在のビューを削除して再追加するだけです (場合によっては、再描画するだけです)。

于 2012-09-05T04:59:43.980 に答える
1

私はいつもこの方法を使用しています。完璧に機能します。あなたにも役立つかもしれません。


every のメソッドで、現在の言語NSLocalizableString(...)の forを使用してすべてのテキストを設定する必要があります。UI-viewWillAppear:UIViewController

この方法を使用すると、設定で言語を変更した後にアプリケーションを再起動する必要がなくなります。iOS


もちろん、Apple の標準的なローカリゼーション アーキテクチャを使用しています。

更新 (2013 年 10 月 24 日)

–viewWillAppear:アプリケーションがフォアグラウンドに入ると、実際のビューに対してメソッドが実行されないことを経験しました。UIApplicationWillEnterForegroundNotificationその問題を解決するために、ビューで通知を受け取ったときに手順 (上記を参照) もコミットします。

于 2012-08-30T09:09:54.573 に答える
-1

このような別のバンドルをロードする必要があります (@"en" は必要なロケールである可能性があります):

NSString *path = [[NSBundle mainBundle] pathForResource:@"en" ofType:@"lproj"];
NSBundle *languageBundle = [NSBundle bundleWithPath:path];

ロードされたバンドルを使用するか、このようにそのバンドルのメソッドを直接使用する NSLocalizedString のようなマクロ/関数を作成します

[languageBundle localizedStringForKey:key value:value table:tableName];

[[NSBundle mainBundle] localizations]すべてのアプリのローカリゼーション (「ベース」を含む) を一覧表示します。

また、これを行うヘルパー クラスを作成しました (依存関係として ReactiveCocoa があることに注意してください)。アプリを再起動せずに言語を変更でき、変更されるたびに現在のロケールを送信します。

于 2015-03-02T15:50:14.100 に答える