質問

iPhoneの場合 NSLocalizedString iPhone の言語で文字列を返します。強制することは可能ですか NSLocalizedString 特定の言語を使用して、アプリをデバイスとは異なる言語で配置するには?

役に立ちましたか?

解決

NSLocalizedString()(およびその変異体)の好適な言語のためのユーザーの設定が何であるかを決定するためにNSUserDefaultsに「AppleLanguages」キーにアクセスします。これは、自分の携帯電話のためにユーザによって設定された一つである最初のもので、言語コードの配列を返し、リソースは言語で利用できない場合、後続のものがフォールバックとして使用します。 (デスクトップ上で、ユーザーがシステム環境設定でカスタムの順序で複数の言語を指定することもできます)。

自分自身の言語のリストを設定する方法:forKey:あなたがsetObjectメソッドを使用して希望の場合は、

あなたは、独自のアプリケーションのグローバル設定を上書きすることができます。これは、グローバル設定値よりも優先されますし、ローカライズを実行しているアプリケーション内の任意のコードに返されます。このためのコードは次のようになります。

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

これはドイツフォールバックとしての英語とフランス語を使用してアプリケーションのための優先言語、になるだろう。あなたは、アプリケーションの起動中に、これはいつか早い呼び出したいでしょう。あなたがここに言語/ロケール設定についての詳細を読むことができます:国際化プログラミングトピック:現在の言語を取得し、ロケール

他のヒント

また、同じ問題と最近は思開始およびパッチっと NSLocalizedString でも、アプリの再起動のための新しい言語です。たいと思ったものとします。

私の溶液を動的に変えるメインバンドルのクラスおよび荷重の適切なバンドルもコメントありがとうございます

ヘッダファイル

@interface NSBundle (Language)
+(void)setLanguage:(NSString*)language;
@end

実施

#import <objc/runtime.h>

static const char _bundle=0;

@interface BundleEx : NSBundle
@end

@implementation BundleEx
-(NSString*)localizedStringForKey:(NSString *)key value:(NSString *)value table:(NSString *)tableName
{
    NSBundle* bundle=objc_getAssociatedObject(self, &_bundle);
    return bundle ? [bundle localizedStringForKey:key value:value table:tableName] : [super localizedStringForKey:key value:value table:tableName];
}
@end

@implementation NSBundle (Language)
+(void)setLanguage:(NSString*)language
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^
    {
        object_setClass([NSBundle mainBundle],[BundleEx class]);
    });
    objc_setAssociatedObject([NSBundle mainBundle], &_bundle, language ? [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:language ofType:@"lproj"]] : nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end

なので基本的には、アプリが開始する前に負荷を最初のコントローラは、単に電話:

[NSBundle setLanguage:@"en"];

時にユーザーの変更等については、優先言語設定画面で通話でしてもらうことを目的として

[NSBundle setLanguage:@"fr"];

リセット後にシステムデフォルトは、単に二つの引数:

[NSBundle setLanguage:nil];

お楽しみ---

が必要な者に対する迅速なバージョン:

var bundleKey: UInt8 = 0

class AnyLanguageBundle: Bundle {

    override func localizedString(forKey key: String,
                                  value: String?,
                                  table tableName: String?) -> String {

        guard let path = objc_getAssociatedObject(self, &bundleKey) as? String,
              let bundle = Bundle(path: path) else {

            return super.localizedString(forKey: key, value: value, table: tableName)
            }

        return bundle.localizedString(forKey: key, value: value, table: tableName)
    }
}

extension Bundle {

    class func setLanguage(_ language: String) {

        defer {

            object_setClass(Bundle.main, AnyLanguageBundle.self)
        }

        objc_setAssociatedObject(Bundle.main, &bundleKey,    Bundle.main.path(forResource: language, ofType: "lproj"), .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    }
}

私は通常、このような方法でこれを実行しますが、プロジェクト内のすべてのローカライズファイルを持っている必要があります。

@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

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

私は、W / Oアプリを再起動し、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, @""));

先に述べたように、ちょうど行います:

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

アプリを再起動することを避けるために。しかし、ちょうどmain.m(...)の前に、UIApplicationMainの主な方法でラインを入れます。

アプリからそれを選択することにより、特定の言語を使用するトリック

、選択した言語に応じて特定のバンドルを使用するNSLocalizedStringを強制することです

ここで私はこのために書かれているポストであります iOSアプリで学習事前ローカライズする

ここでIOSアプリケーションに予め局在化つのサンプルアプリケーション

ブライアン・ウェブスターは述べて通り

、言語は「いつか早いアプリケーションの起動中」に設定する必要があります。私は他のすべての初期化を行う場所、それはだからapplicationDidFinishLaunching:AppDelegateは、それを行うには、適切な場所であるべきと思っています。

しかし、ウィリアム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;
}

私はこの上の任意のコメントをいただければと思います。

あなたはスウィフト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.

私はマウロDelrioの方法が一番好き。 私はまた私のProject_Prefix.pchに以下を追加した。

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

あなたは今まであなたがすべてのファイルに素早く構文置換を行うことができます(つまり、NSLocalizedStringを使用しています)標準的な方法を使用したいので、もします。

NSLocalizedString()は、標準的なユーザデフォルト(AppleLanguages)からキー[NSUserDefaults standardUserDefaults]の値を読み出します。これは、実行時に、既存のすべてのローカライズの間で適切なローカライズを選択し、その値を使用しています。 Appleはアプリの起動時にユーザデフォルト辞書を構築するとき、彼らは好みの言語(S)システム環境設定でキーを検索し、そこから値をコピーします。 OS Xで言語設定を変更するだけでその後始まっアプリに、アプリケーションを実行するには影響を与えません理由は、例えば説明しています。コピーした後は、値が設定を変更するという理由だけで更新されません。あなたは、言語を変更した場合のiOSは、すべてのアプリケーションを再起動する理由です。

ただし、のすべての値のユーザデフォルト辞書のは、コマンドライン引数で上書きすることができます。 NSUserDefaultsNSArgumentDomainドキュメントを参照してください。これも、アプリの好み(の.plist)ファイルからロードされ、それらの値を含んでいます。これはテストのために一度だけ値を変更したい場合は、のを知って本当に良いです。

あなただけのテストのために言語を変更したい場合、あなたはおそらく(あなたが...後で、このコードを削除するのを忘れた場合)あなたのコードを変更する必要はありませんので、

、代わりにコマンドを使用してアプリを起動するためのXcodeを伝えますラインパラメータ(例えばスペイン語のローカライズを使用):

ここに画像の説明を入力します

で、すべてのコードに触れる必要はありません。ただ、異なる言語の異なるスキームを作成し、すばやくだけの方式を切り替えることで、別の1で一度一つの言語に一度アプリを起動することができます。

私はあなたがNSLocalizedStringを使用することができます解決策を考え出しました。私はNSBundleコール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を追加したより。

私はAppDelegateの財産で私の言語コードを保存見ることができるように。これは、あなたが好きな任意の場所に保存することができます。

私はそれについて好きではないこれだけの事はマルコが再定義NSLocalizedString警告です。おそらく誰かが私はこの部分を修正するのに役立つ可能性があります。

スウィフトバージョン:

NSUserDefaults.standardUserDefaults().setObject(["fr"], forKey: "AppleLanguages")
NSUserDefaults.standardUserDefaults().synchronize()

このように:

豊用

って最初にすることでもいいですが、localiseアプリの少なくとも二言語(英語、フランス語。

オーバーライドNSLocalizedString

コードを使わずに NSLocalizedString(key, comment), 利用マクロ MYLocalizedString(key, comment) 定義のようになります:#define MYLocalizedString(key, comment) [[MYLocalizationSystem sharedInstance] localizedStringForKey:(key) value:(comment)];

この MYLocalizationSystem singletonます:

  • 設定言語設定により権利 局所NSBundle ユーザーが求めら
  • を返します 局所NSString に従って設定された言語

ユーザーの言語設定

ユーザーの変更申請語フランス語で話 [[MYLocalizationSystem sharedInstance] setLanguage:@"fr"];

- (void)setLanguage:(NSString *)lang
{
    NSString *path = [[NSBundle mainBundle] pathForResource:lang ofType:@"lproj"];
    if (!path)
    {
        _bundle = [NSBundle mainBundle];
        NSLog(@"Warning: No lproj for %@, system default set instead !", lang);
        return;
    }

    _bundle = [NSBundle bundleWithPath:path];
}

この例では この方法でセット局所的なバンドルにはございません。lproj

地域対応された文字列を返し

お客さま人数小児-幼児にセットの局在を束ねることができる、正しい知識を身につけましょうローカルな文字列からこの方法:

- (NSString *)localizedStringForKey:(NSString *)key value:(NSString *)value
{
    // bundle was initialized with [NSBundle mainBundle] as default and modified in setLanguage method
    return [self.bundle localizedStringForKey:key value:value table:nil];
}

これがお手伝いいたします。

だ詳細はこの記事 NSWinery.io

迅速な3つの拡張:

extension Locale {
    static var preferredLanguage: String {
        get {
            return self.preferredLanguages.first ?? "en"
        }
        set {
            UserDefaults.standard.set([newValue], forKey: "AppleLanguages")
            UserDefaults.standard.synchronize()
        }
    }
}

extension String {
    var localized: String {

    var result: String

    let languageCode = Locale.preferredLanguage //en-US

    var path = Bundle.main.path(forResource: languageCode, ofType: "lproj")

    if path == nil, let hyphenRange = languageCode.range(of: "-") {
        let languageCodeShort = languageCode.substring(to: hyphenRange.lowerBound) // en
        path = Bundle.main.path(forResource: languageCodeShort, ofType: "lproj")
    }

    if let path = path, let locBundle = Bundle(path: path) {
        result = locBundle.localizedString(forKey: self, value: nil, table: nil)
    } else {
        result = NSLocalizedString(self, comment: "")
    }
        return result
    }
}

使用量:

Locale.preferredLanguage = "uk"

label.text = "localizedKey".localized

ファイルでの .PCH を定義します。

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


#define NSLocalizedString(str,nil) NSLocalizedStringFromTableInBundle(str, nil, currentLanguageBundle, @"")

たぶん、あなたは(#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]

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

私は2つのローカライズされたファイル、JAを持っている私の場合のために、専用

と私はENにそれを強制したい場合、システム内の好みの言語でもないエンまたはJA

私はmain.mファイルを編集するつもりです。

私はっ好ましい第一は、ENまたはJAであるか否かをチェック、そうでない場合、私は、「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]));


    }


}

スウィフト3溶液ます:

let languages = ["bs", "zh-Hant", "en", "fi", "ko", "lv", "ms", "pl", "pt-BR", "ru", "sr-Latn", "sk", "es", "tr"]
UserDefaults.standard.set([languages[0]], forKey: "AppleLanguages")

を使用することができる言語コードのいくつかの例を与えました。ホープ、このことができます。

あなたはこのような何かを行うことができます:

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


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

NSLocalizedStringFromTableInBundle(@"House", nil, spanishBundle, nil):

アプリケーションを残したり再起動せずに言語を変更するには、をTudorizerのの回答に基づいて。

の代わりにマクロ、特定の言語のコードが存在するかどうかを確認するために、優先言語にアクセスするためのクラスを使用します。

以下は、iOSの9のために働いている現在の言語バンドルを取得するために使用するクラスです。

@implementation OSLocalization

+ (NSBundle *)currentLanguageBundle
{
    // Default language incase an unsupported language is found
    NSString *language = @"en";

    if ([NSLocale preferredLanguages].count) {
        // Check first object to be of type "en","es" etc
        // Codes seen by my eyes: "en-US","en","es-US","es" etc

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

        if ([letterCode rangeOfString:@"en"].location != NSNotFound) {
            // English
            language = @"en";
        } else if ([letterCode rangeOfString:@"es"].location != NSNotFound) {
            // Spanish
            language = @"es";
        } else if ([letterCode rangeOfString:@"fr"].location != NSNotFound) {
            // French
            language = @"fr";
        } // Add more if needed
    }

    return [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:language ofType:@"lproj"]];
}

/// Check if preferred language is English
+ (BOOL)isCurrentLanguageEnglish
{
    if (![NSLocale preferredLanguages].count) {
        // Just incase check for no items in array
        return YES;
    }

    if ([[[NSLocale preferredLanguages] objectAtIndex:0] rangeOfString:@"en"].location == NSNotFound) {
        // No letter code for english found
        return NO;
    } else {
        // Tis English
        return YES;
    }
}

/*  Swap language between English & Spanish
 *  Could send a string argument to directly pass the new language
 */
+ (void)changeCurrentLanguage
{
    if ([self isCurrentLanguageEnglish]) {
        [[NSUserDefaults standardUserDefaults] setObject:@[@"es"] forKey:@"AppleLanguages"];
    } else {
        [[NSUserDefaults standardUserDefaults] setObject:@[@"en"] forKey:@"AppleLanguages"];
    }
}
@end

文字列ファイル/画像/動画/などを参照するために上記のクラスを使用します:

// Access a localized image
[[OSLocalization currentLanguageBundle] pathForResource:@"my_image_name.png" ofType:nil]
// Access  a localized string from Localizable.strings file
NSLocalizedStringFromTableInBundle(@"StringKey", nil, [OSLocalization currentLanguageBundle], @"comment")
以下のようなイン・ライン

言語の変更や新しい言語を参照する文字列パラメータを取るために上記のクラスで「changeCurrentLanguage」メソッドを更新します。

[[NSUserDefaults standardUserDefaults] setObject:@[@"es"] forKey:@"AppleLanguages"];

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

- (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;
}

私は正式にiOSの(システム設定で言語のセクションに記載されていない)でサポートされていない言語のサポートを追加したいです。 Appleの国際化のチュートリアルrel="nofollow">のとブライアン・ウェブスターとゼオンことで、ここでいくつかのヒント、私は、コードのこの部分(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]));
    }
}

このストーリーボードとNSLocalizedStringコードの両方に適しています。コードは、ユーザーが後で手動でアプリ内の言語を変更するオプションを持っていることを前提としています。

もちろん、適切なストーリーボードの翻訳とのLocalizable.stringsの翻訳を追加することを忘れないでください(ことを行う方法について先にアップルのページへのリンクを参照してください)。

ここでは、この問題のためにまともなソリューションであり、それはアプリケーションの再起動を必要としません。

https://github.com/cmaftuleac/BundleLocalizationする

この実装は、NSBundleの内側にひねることによって動作します。アイデアは、あなたがNSBundleオブジェクトのインスタンスでのメソッドlocalizedStringForKeyを上書きして、異なる言語で異なるバンドル上でこのメソッドを呼び出すことです。すべてのタイプのリソースと完全に互換性シンプルかつエレガントます。

SWIFT 4では、私は、ライブラリを再起動するか、使用しなくても、それを解決した。

多くのオプションを試した後、私はあなたが翻訳したいというあなたは(Localizable.String、文字列ファイルの)stringToLocalizeを渡し、この機能を、見つけ、そしてあなたがそれを翻訳する言語、そして何が返すことですあなたは文字列ファイルに持っている文字列の値:

    func localizeString (stringToLocalize: String, language: String) -> String
    {
        let path = Bundle.main.path (forResource: language, ofType: "lproj")
        let languageBundle = Bundle (path: path!)
        return languageBundle! .localizedString (forKey: stringToLocalize, value: "", table: nil)
    }

のアカウントにこの機能を考えると、私はスウィフトのファイルにこの関数を作成します:

struct CustomLanguage {

    func createBundlePath () -> Bundle {
        let selectedLanguage = //recover the language chosen by the user (in my case, from UserDefaults)
        let path = Bundle.main.path(forResource: selectedLanguage, ofType: "lproj")
        return Bundle(path: path!)!
    }
}

全体のアプリから、代わりに置くのViewControllersの残りの各文字列にアクセスするには:

NSLocalizedString ("StringToLocalize", comment: “")

私はそれを交換した。

let customLang = CustomLanguage() //declare at top
let bundleLanguage = customLang.createBundle()

NSLocalizedString("StringToLocalize", tableName: nil, bundle: bundleLanguage, value: "", comment: “”) //use in each String

それが最善の方法だ場合、私は知らないが、私はそれは非常に単純な発見し、それは私の作品、私はそれがあなたの役に立てば幸い!

あなたのすべてがそう何でも、最良の方法は、指定された言語のためにすなわち:FR、EN、NL、デ、それなどをSHORT_NAMEを取る...とグローバル値に同じを割り当てることです。

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

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

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

壊れていないルールます。

スウィフトのためには、main.swiftファイルを上書きすることができますし、あなたのアプリの実行前に存在しUserDefaults文字列を設定します。この方法は、あなたは、所望の効果を確認するためにアプリケーションを再起動する必要はありません。

import Foundation
import UIKit

// Your initialisation code here
let langCultureCode: String = "LANGUAGE_CODE"

UserDefaults.standard.set([langCultureCode], forKey: "AppleLanguages")
UserDefaults.standard.synchronize()

UIApplicationMain(CommandLine.argc, CommandLine.unsafeArgv, nil, NSStringFromClass(AppDelegate.self))

@UIApplicationMainファイル内AppDelegate.swiftの除去と一緒にペアになっています。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top