269

On iPhoneNSLocalizedStringは、文字列を iPhone の言語で返します。特定の言語を強制的NSLocalizedStringに使用して、アプリをデバイスとは異なる言語にすることはできますか?

4

28 に答える 28

263

NSLocalizedString()(およびその亜種) は、"AppleLanguages" キーにアクセスしてNSUserDefaults、優先言語に対するユーザーの設定を判断します。これは、言語コードの配列を返します。最初のコードはユーザーが自分の電話に設定したもので、後続のコードは優先言語でリソースが利用できない場合にフォールバックとして使用されます。(デスクトップでは、ユーザーはシステム環境設定のカスタム順序で複数の言語を指定できます)

必要に応じて、setObject:forKey: メソッドを使用して独自の言語リストを設定することにより、独自のアプリケーションのグローバル設定をオーバーライドできます。これは、グローバルに設定された値よりも優先され、ローカライズを実行しているアプリケーション内のすべてのコードに返されます。このコードは次のようになります。

[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:@"de", @"en", @"fr", nil] forKey:@"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] synchronize]; //to make the change immediate

これにより、ドイツ語がアプリケーションの優先言語になり、英語とフランス語が代替言語になります。アプリケーションの起動の早い段階でこれを呼び出す必要があります。言語/ロケール設定の詳細については、こちらを参照してください:国際化プログラミングのトピック: 現在の言語とロケールの取得

于 2009-11-03T22:23:38.007 に答える
137

私は通常、この方法でこれを行いますが、プロジェクトにはすべてのローカライズ ファイルが必要です。

@implementation Language

static NSBundle *bundle = nil;

+(void)initialize 
{
    NSUserDefaults* defs = [NSUserDefaults standardUserDefaults];
    NSArray* languages = [defs objectForKey:@"AppleLanguages"];
    NSString *current = [[languages objectAtIndex:0] retain];
    [self setLanguage:current];
}

/*
  example calls:
    [Language setLanguage:@"it"];
    [Language setLanguage:@"de"];
*/
+(void)setLanguage:(NSString *)l
{
    NSLog(@"preferredLang: %@", l);
    NSString *path = [[ NSBundle mainBundle ] pathForResource:l ofType:@"lproj" ];
    bundle = [[NSBundle bundleWithPath:path] retain];
}

+(NSString *)get:(NSString *)key alter:(NSString *)alternate 
{
    return [bundle localizedStringForKey:key value:alternate table:nil];
}

@end
于 2009-11-17T06:11:10.297 に答える
41

iOS 9 では使用しないでください。これは、渡されたすべての文字列に対して nil を返します。

アプリを再起動せず、genstrings と互換性があり、言語文字列を更新できる別のソリューションを見つけました。

このマクロを Prefix.pch に入れます。

#define currentLanguageBundle [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:[[NSLocale preferredLanguages] objectAtIndex:0] ofType:@"lproj"]]

ローカライズされた文字列が必要な場合は、次のように使用します。

NSLocalizedStringFromTableInBundle(@"GalleryTitleKey", nil, currentLanguageBundle, @"")

言語を設定するには:

[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObject:@"de"] forKey:@"AppleLanguages"];

次のような連続した言語ホッピングでも機能します。

NSLog(@"test %@", NSLocalizedStringFromTableInBundle(@"NewKey", nil, currentLanguageBundle, @""));
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObject:@"fr"] forKey:@"AppleLanguages"];
NSLog(@"test %@", NSLocalizedStringFromTableInBundle(@"NewKey", nil, currentLanguageBundle, @""));
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObject:@"it"] forKey:@"AppleLanguages"];
NSLog(@"test %@", NSLocalizedStringFromTableInBundle(@"NewKey", nil, currentLanguageBundle, @""));
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObject:@"de"] forKey:@"AppleLanguages"];
NSLog(@"test %@", NSLocalizedStringFromTableInBundle(@"NewKey", nil, currentLanguageBundle, @""));
于 2011-10-28T18:40:43.217 に答える
32

アプリから選択して特定の言語を使用するトリックはNSLocalizedString、選択した言語に応じて特定のバンドルを強制的に使用することです。

これは、iOSアプリでの高度なローカリゼーションの学習のために私が書いた投稿 です

これは、iOS アプリでの 1 つのサンプル アプリの高度なローカリゼーションのコードです。

于 2011-05-01T17:33:57.073 に答える
32

前述のように、次のようにします。

[[NSUserDefaults standardUserDefaults] setObject: [NSArray arrayWithObjects:@"el", nil] forKey:@"AppleLanguages"];

ただし、アプリを再起動する必要がないように、(...)のmain.m直前に, のメイン メソッドに行を挿入します。UIApplicationMain

于 2010-06-25T12:44:19.003 に答える
15

Swift 3 のこのソリューションについてどう思いますか?

extension String {

    func localized(forLanguage language: String = Locale.preferredLanguages.first!.components(separatedBy: "-").first!) -> String {

        guard let path = Bundle.main.path(forResource: language == "en" ? "Base" : language, ofType: "lproj") else {

            let basePath = Bundle.main.path(forResource: "Base", ofType: "lproj")!

            return Bundle(path: basePath)!.localizedString(forKey: self, value: "", table: nil)
        }

        return Bundle(path: path)!.localizedString(forKey: self, value: "", table: nil)
    }
}

簡単な使い方:

"report".localized(forLanguage: "pl") //forced language
"report".localized() //default language selected by user in settings, in case when your app doesnt support selected lanaguage, the default one is selected, here is an english.
于 2016-12-13T14:39:45.933 に答える
14

Brian Webster が言及しているように、言語は「アプリケーションの起動の早い段階で」設定する必要があります。他のすべての初期化を行う場所であるため、それを行うのに適した場所であるapplicationDidFinishLaunching:と考えました。AppDelegate

しかし、William Denniss が言及しているように、それはアプリが再起動されたにのみ効果があるようで、これは役に立たない.

ただし、コードをメイン関数に入れるとうまくいくようです:

int main(int argc, char *argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    // Force language to Swedish.
    [[NSUserDefaults standardUserDefaults]
     setObject:[NSArray arrayWithObject:@"sv"]
     forKey:@"AppleLanguages"];

    int retVal = UIApplicationMain(argc, argv, nil, nil);
    [pool release];
    return retVal;
}

これについてコメントをいただければ幸いです。

于 2010-09-01T22:04:44.897 に答える
13

NSLocalizedString()AppleLanguages標準のユーザー デフォルト ( ) からキーの値を読み取ります[NSUserDefaults standardUserDefaults]。その値を使用して、実行時にすべての既存のローカライズから適切なローカライズを選択します。Apple がアプリの起動時にユーザー デフォルト辞書を作成するとき、システム設定で優先言語キーを検索し、そこから値をコピーします。これは、たとえば、OS X で言語設定を変更しても実行中のアプリには影響せず、その後起動したアプリにのみ影響する理由も説明しています。コピーすると、設定が変更されたという理由だけで値が更新されることはありません。そのため、言語を変更すると、iOS はすべてのアプリを再起動します。

ただし、ユーザー デフォルト ディクショナリのすべての値は、コマンド ライン引数で上書きできます。NSUserDefaultsのドキュメントを参照してくださいNSArgumentDomain。これには、アプリの設定 (.plist) ファイルから読み込まれた値も含まれます。テストのために一度だけ値を変更したい場合は、これを知っておくと便利です。

したがって、テストのためだけに言語を変更したい場合は、おそらくコードを変更したくないでしょう (後でこのコードを削除するのを忘れた場合...)。代わりに、コマンド ライン パラメーターを使用してアプリを起動するように Xcode に指示します (例: スペイン語のローカライズを使用):

ここに画像の説明を入力

コードに触れる必要はまったくありません。言語ごとに異なるスキームを作成するだけで、スキームを切り替えるだけで、ある言語で 1 回、別の言語で 1 回、アプリをすばやく起動できます。

于 2014-09-10T10:28:02.423 に答える
12

私はマウロ・デルリオの方法が一番好きです。Project_Prefix.pch に以下も追加しました

#import "Language.h"    
#define MyLocalizedString(key, alt) [Language get:key alter:alt]

したがって、標準の方法 (NSLocalizedString を使用する) を使用したい場合は、すべてのファイルで簡単な構文置換を行うことができます。

于 2011-01-27T12:38:26.663 に答える
10

を使用できるようにするソリューションを思いつきましたNSLocalizedStringNSBundlecallのカテゴリを作成しますNSBundle+RunTimeLanguage。インターフェースはこんな感じ。

// NSBundle+RunTimeLanguage.h
#import <Foundation/Foundation.h>
@interface NSBundle (RunTimeLanguage)
#define NSLocalizedString(key, comment) [[NSBundle mainBundle] runTimeLocalizedStringForKey:(key) value:@"" table:nil]
- (NSString *)runTimeLocalizedStringForKey:(NSString *)key value:(NSString *)value table:(NSString *)tableName;
@end

実装はこんな感じ。

// NSBundle+RunTimeLanguage.m
#import "NSBundle+RunTimeLanguage.h"
#import "AppDelegate.h"

@implementation NSBundle (RunTimeLanguage)

- (NSString *)runTimeLocalizedStringForKey:(NSString *)key value:(NSString *)value table:(NSString *)tableName
{
    AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
    NSString *path= [[NSBundle mainBundle] pathForResource:[appDelegate languageCode] ofType:@"lproj"];
    NSBundle *languageBundle = [NSBundle bundleWithPath:path];
    NSString *localizedString=[languageBundle localizedStringForKey:key value:key table:nil];
    return localizedString;
}
@end

NSBundle+RunTimeLanguage.hを使用するファイルにインポートを追加するだけではありませんNSLocalizedString

ご覧のとおり、languageCode を のプロパティに保存しますAppDelegate。これは、好きな場所に保存できます。

私が気に入らない唯一のことは、マルコがNSLocalizedString再定義した警告です。おそらく、誰かがこの部分を修正するのを手伝ってくれるでしょう。

于 2014-04-30T18:53:58.573 に答える
5

ファイル.pchで次を定義します。

#define currentLanguageBundle [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:[[NSLocale preferredLanguages] objectAtIndex:0] ofType:@"lproj"]]


#define NSLocalizedString(str,nil) NSLocalizedStringFromTableInBundle(str, nil, currentLanguageBundle, @"")
于 2013-03-13T15:19:27.580 に答える
4

たぶん、これを補完する必要があります( #import の後の .pch ファイルで):

extern NSBundle* bundle; // Declared on Language.m

#ifdef NSLocalizedString
    #undef NSLocalizedString
    // Delete this line to avoid warning
    #warning "Undefining NSLocalizedString"
#endif

#define NSLocalizedString(key, comment) \
    [bundle localizedStringForKey:(key) value:@"" table:nil]
于 2011-08-04T15:22:11.360 に答える
3

これを実行するローカライズされた文字列のセットを使用してサブバンドルを作成し、NSLocalizedStringFromTableInBundle()それらをロードするために使用できます。(これは、アプリで実行している可能性のある通常のUIローカリゼーションとは別のコンテンツであると想定しています。)

于 2009-11-03T19:51:36.577 に答える
3

私の場合、ja と en の 2 つのローカライズされたファイルがあります。

システムの優先言語がenでもjaでもない場合は、enに強制したいと思います

main.m ファイルを編集します

最初に優先する言語が en か ja かを確認し、そうでない場合は、2 番目に優先する言語を en に変更します。

int main(int argc, char *argv[])
{

    [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"AppleLanguages"];
    [[NSUserDefaults standardUserDefaults] synchronize];

    NSString *lang = [[NSLocale preferredLanguages] objectAtIndex:0];

    if (![lang isEqualToString:@"en"]  &&  ![lang isEqualToString:@"ja"]){

        NSMutableArray *array = [[NSMutableArray alloc] initWithArray:[NSLocale preferredLanguages]];
        [array replaceObjectAtIndex:1 withObject:@"en"];

        [[NSUserDefaults standardUserDefaults] setObject:array forKey:@"AppleLanguages"];
        [[NSUserDefaults standardUserDefaults] synchronize];


    }

    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));


    }


}
于 2014-04-02T08:40:51.467 に答える
2

次のようなことができます。

NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"Localizable" ofType:@"strings" inDirectory:nil forLocalization:@"es"];


NSBundle *spanishBundle = [[NSBundle alloc] initWithPath:[bundlePath stringByDeletingLastPathComponent]];

NSLocalizedStringFromTableInBundle(@"House", nil, spanishBundle, nil):
于 2014-11-17T20:59:51.180 に答える
1

この関数は、現在の言語のローカライズされた文字列を取得しようとします。見つからない場合は、英語を使用して取得します。

- (NSString*)L:(NSString*)key
{
    static NSString* valueNotFound = @"VALUE_NOT_FOUND";
    static NSBundle* enBundle = nil;

    NSString* pl = [NSLocale preferredLanguages][0];
    NSString* bp = [[NSBundle mainBundle] pathForResource:pl ofType:@"lproj"];
    NSBundle* b = [NSBundle bundleWithPath:bp];

    NSString* s = [b localizedStringForKey:key value:valueNotFound table:nil];
    if ( [s isEqualToString:valueNotFound] ) {
        if ( !enBundle ) {
            bp = [[NSBundle mainBundle] pathForResource:@"en" ofType:@"lproj"];
            enBundle = [NSBundle bundleWithPath:bp];
        }
        s = [enBundle localizedStringForKey:key value:key table:nil];
    }

    return s;
}
于 2013-06-17T08:41:07.140 に答える
1

iOS で公式にサポートされていない言語のサポートを追加したかった (システム設定の [言語] セクションにリストされていない)。Apple の Internationalization Tutorialと、Brian Webster と geon によるいくつかのヒントに従って、このコードを思いつきました (main.m に入れます)。

int main(int argc, char * argv[]) {
    @autoreleasepool {
        // Grab regional settings locale, for Slovenian this is either sl_SI or en_SI
        NSLocale *locale = [NSLocale currentLocale];
        NSString *ll = [locale localeIdentifier]; // sl_SI

        // Grab the first part of language identifier
        NSArray *comp = [ll componentsSeparatedByString:@"_"];
        NSString *ll1 = @"en";
        if (comp.count > 0) {
            ll1 = comp[0]; // sl, en, ...
        }
        // Check if we already saved language (user can manually change it inside app for example)
        if (![[NSUserDefaults standardUserDefaults] objectForKey:@"SelectedLanguage"]) {
            //   Slovenian (Slovenia),            Slovenia
            if ([ll isEqualToString:@"sl_SI"] || [ll isEqualToString:@"en_SI"]) {
                ll1 = @"sl-SI"; // This is the part of localized path for Slovenian language that Xcode generates
            }
            // Add more unsupported languages here...

            [[NSUserDefaults standardUserDefaults] setObject:ll1 forKey:@"SelectedLanguage"]; // Save language
        }
        else {
            // Restore language as we have previously saved it
            ll1 = [[NSUserDefaults standardUserDefaults] objectForKey:@"SelectedLanguage"];
        }
        // Overwrite NSLocalizedString and StoryBoard language preference
        [[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:ll1, @"en", @"fr", nil] forKey:@"AppleLanguages"];
        // Make sure settings are stored to disk
        [[NSUserDefaults standardUserDefaults] synchronize];

        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

これは、Storyboard と NSLocalizedString コードの両方でうまく機能します。このコードは、ユーザーが後でアプリ内の言語を手動で変更するオプションを持っていることを前提としています。

もちろん、適切な Storyboard 翻訳と Localizable.strings 翻訳を追加することを忘れないでください (方法については、上記の Apple ページへのリンクを参照してください)。

于 2013-10-09T19:23:34.873 に答える
0

何をするにせよ、最善の方法は、指定された言語の short_name を取得することです。つまり、fr、en、nl、de、it など... をグローバル値に割り当てます。

ピッカー ビューをドロップ ダウン メニューのようにポップアップするようにし (クリックするとピッカー ビューが下から表示されるボタンと言語のリストを組み合わせたもの)、目的の言語を選択します。短い名前を内部に保存します。LocalizedString という名前の .h + .m ファイルを作成します。

short_name のグローバル値を、LocalisedString.m で取得した値と等しくなるように設定します。必要な言語を選択したら、NSBundlePath を割り当てて、必要な言語のプロジェクト サブディレクトリを作成します。たとえば、nl.proj、en.proj です。

特定の proj フォルダーを選択すると、それぞれの言語のローカライズされた文字列が呼び出され、言語が動的に変更されます。

規則違反はありません。

于 2011-08-12T11:17:35.487 に答える