Question

Sur iPhone NSLocalizedString retourne une chaîne de caractères dans la langue de l'iPhone.Est-il possible de forcer NSLocalizedString pour utiliser une langue spécifique à l'application dans une langue différente de celle de l'appareil ?

Était-ce utile?

La solution

NSLocalizedString() (et ses variantes) pour accéder à la "AppleLanguages" clés en NSUserDefaults pour déterminer ce que les paramètres de l'utilisateur pour les langues préférées sont.Cette fonction retourne un tableau des codes de langue, avec la première étant celle définie par l'utilisateur pour leur téléphone, et les suivants utilisé comme base si une ressource n'est pas disponible dans la langue préférée.(sur le bureau, l'utilisateur peut spécifier plusieurs langues avec une coutume de la commande dans les Préférences Système)

Vous pouvez remplacer le paramètre par défaut pour votre application si vous le souhaitez en utilisant le setObject:forKey:méthode pour définir votre propre liste de langues.Cela aura préséance sur le définir globalement la valeur et être renvoyé à tout le code de votre application qui effectue la localisation.Le code pour que cela ressemblerait à quelque chose comme:

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

Ce serait faire de l'allemand la langue de votre demande, l'anglais et le français de base.Vous souhaitez appeler ce jour tôt dans votre démarrage de l'application.Vous pouvez lire plus au sujet de la langue/préférences locales ici: L'Internationalisation Des Sujets De Programmation:L'obtention de la Langue et les paramètres Régionaux

Autres conseils

J'ai eu le même problème récemment et je ne voulais pas commencer et patcher toute ma NSLocalizedString ni forcer l'application à redémarrer pour la nouvelle langue de travail. Je voulais que tout fonctionne comme-est.

était à ma solution modifier dynamiquement la classe du paquet principal et charger le paquet il approprié:

fichier d'en-tête

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

Mise en œuvre

#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

Donc, fondamentalement, au démarrage de votre application et avant de charger votre premier contrôleur, il suffit d'appeler:

[NSBundle setLanguage:@"en"];

Lorsque votre utilisateur change sa langue préférée dans votre écran de réglage, il suffit d'appeler à nouveau:

[NSBundle setLanguage:@"fr"];

Pour rétablir les paramètres par défaut du système, il suffit de passer nulle:

[NSBundle setLanguage:nil];

Enjoy ...

Pour ceux qui ont besoin d'une version Swift:

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)
    }
}

je fais d'habitude ce de cette façon, mais vous devez avoir tous les fichiers de localisation dans votre projet.

@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

Ne pas utiliser sur iOS 9. Cela renvoie zéro pour toutes les chaînes passées à travers elle.

Je l'ai trouvé une autre solution qui vous permet de mettre à jour les chaînes de langue, w / o redémarrer l'application et compatible avec genstrings:

Mettre cette macro dans le Prefix.pch:

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

et où jamais vous avez besoin d'une utilisation de chaîne localisée:

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

Pour définir l'utilisation de la langue:

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

Fonctionne même avec la langue consécutive sautillant comme:

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, @""));

Comme dit précédemment, il suffit de faire:

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

Mais pour éviter d'avoir à redémarrer l'application, mettre la ligne dans la principale méthode de main.m, juste avant UIApplicationMain (...).

L'astuce d'utiliser un langage spécifique en le sélectionnant dans l'application est de forcer le NSLocalizedString à utiliser ensemble spécifique en fonction de la langue sélectionnée,

Voici le message que je l'ai écrit pour ce localisation avance apprentissage dans ios applications

et voici le code d'un exemple d'application localisation avance dans les applications de ios

Brian Webster mentionne, la langue doit être perçu « quelque temps au début de la mise en service de votre application ». Je pensais que applicationDidFinishLaunching: du AppDelegate devrait être un endroit approprié pour le faire, car il est là où je fais tout autre initialisation.

Mais comme William Denniss mentionne, qui semble avoir un effet que après l'application est redémarrée, qui est un peu inutile.

Il semble fonctionner très bien si je mets le code dans la fonction principale, bien que:

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

Je vous remercie de vos commentaires à ce sujet.

Que pensez-vous de cette solution pour 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)
    }
}

Utilisation simple:

"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.

Je préfère la méthode de Mauro Delrio. J'ai également ajouté ce qui suit dans mon Project_Prefix.pch

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

Donc, si jamais vous voulez utiliser la méthode standard (qui utilise NSLocalizedString), vous pouvez faire un changement de syntaxe rapide dans tous les fichiers.

NSLocalizedString() lit la valeur de la clé AppleLanguages à partir de la norme de l'utilisateur par défaut ([NSUserDefaults standardUserDefaults]).Il utilise cette valeur pour choisir une localisation parmi toutes les localisations au moment de l'exécution.Quand Apple s'appuie l'utilisateur par défaut du dictionnaire à l'application de lancement, ils recherchent la langue préférée(s) - clé dans le système de préférences et de copier la valeur à partir de là.Ceci explique par exemple pourquoi changer les paramètres de langue dans OS X n'a pas d'effet sur l'exécution des applications, uniquement sur les applications commencé par la suite.Une fois copié, la valeur n'est pas mis à jour tout simplement parce que la modification des paramètres.C'est pourquoi iOS redémarre toutes les applications, si vous modifiez ensuite la langue.

Cependant, toutes les valeurs de l'utilisateur par défaut du dictionnaire peuvent être remplacées par des arguments de ligne de commande.Voir NSUserDefaults la documentation sur le NSArgumentDomain.Cela inclut même les valeurs qui sont chargés de l'application des préférences (.plist) fichier.C'est vraiment bon à savoir si vous voulez modifier une valeur juste une fois pour le test.

Donc, si vous voulez changer la langue juste pour le test, vous ne voulez probablement pas à modifier votre code (si vous oubliez de retirer ce code un peu plus tard ...), au lieu de dire Xcode pour démarrer votre application avec des paramètres de ligne de commande (par ex.l'utilisation de l'espagnol de localisation):

enter image description here

Pas besoin de toucher votre code.Il suffit de créer différents modèles pour les différentes langues et vous pouvez commencer rapidement à l'application une seule fois dans une seule langue et une seule fois dans l'autre par juste de commutation du régime.

Je suis venu avec une solution qui vous permet d'utiliser NSLocalizedString. Je crée une catégorie de NSBundle d'appel NSBundle+RunTimeLanguage. L'interface est comme ça.

// 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

La mise en œuvre est comme celui-ci.

// 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

que juste ajouter NSBundle+RunTimeLanguage.h d'importation dans les fichiers qui utilisent NSLocalizedString.

Comme vous pouvez le voir, je stocker mon languageCode dans une propriété de AppDelegate. Cela pourrait être stocké partout où vous le souhaitez.

Cette seule chose que je ne l'aime pas à ce sujet est un avertissement que NSLocalizedString marco redéfinie. Peut-être que quelqu'un pourrait me aider à résoudre cette partie.

Swift Version:

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

En bref:

traduisez votre application

Il est la première chose que vous devez faire est de localiser votre application avec au moins deux langues (anglais et français dans cet exemple).

Priorité NSLocalizedString

Dans votre code, au lieu d'utiliser NSLocalizedString(key, comment), utilisez une MYLocalizedString(key, comment) macro définie comme ceci: #define MYLocalizedString(key, comment) [[MYLocalizationSystem sharedInstance] localizedStringForKey:(key) value:(comment)];

Cette singleton MYLocalizationSystem sera:

  • Définir en définissant le langage droite NSBundle localisé utilisateur demande
  • Retourne le NSString localisé selon cette langue définie précédemment

Définir la langue de l'utilisateur

Lorsque la langue de l'application a changé l'utilisateur en français, appelez [[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];
}

Dans cet exemple, cet ensemble de méthode faisceau localisé à fr.lproj

Retour chaîne localisée

Une fois que vous avez défini le faisceau localisé, vous serez en mesure d'obtenir la bonne chaîne localisée de lui avec cette méthode:

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

Espérons que cela vous aidera.

Vous trouverez plus de détails dans cet article NSWinery.io

Swift 3 extensions:

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

Utilisation:

Locale.preferredLanguage = "uk"

label.text = "localizedKey".localized

Dans le fichier .pch pour définir:

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


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

Peut-être que vous devriez compléter ce (le fichier .pch après #import):

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]

Vous pouvez construire un sous-ensemble de l'ensemble de chaînes localisées que vous voulez faire avec, puis utilisez NSLocalizedStringFromTableInBundle() pour les charger. (Je suppose que ce contenu distinct de la localisation de l'interface utilisateur normale, vous pourriez faire sur l'application.)

pour mon cas j'ai deux fichiers localisés, ja et en

et je voudrais l'obliger à en si la langue préférée dans le système ni en ou ja

Je vais modifier le fichier main.m

Je vais vérifier si le premier est préféré en ou ja, sinon je vais changer la deuxième langue préférée pour 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]));


    }


}

Swift 3 solution:

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")

A donné quelques exemples de codes linguistiques qui peuvent être utilisés. Espérons que cela aide

Vous pouvez faire quelque chose comme ceci:

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


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

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

Basé sur de Tudorizer réponse à changer la langue sans quitter ou redémarrer l'application.

Au lieu d'une macro, utilisez une classe pour accéder à la langue préférée afin de vérifier si un code de langue spécifique est présente.

Voici une classe utilisée pour obtenir le faisceau de langage courant qui fonctionne pour 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

Utilisez la classe ci-dessus pour référencer un fichier de chaîne / image / vidéo / etc:

// 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")

Changer de langue en ligne comme ci-dessous ou mettre à jour la méthode « changeCurrentLanguage » dans la classe ci-dessus pour prendre un paramètre de chaîne faisant référence à la nouvelle langue.

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

Cette fonction tentera d'obtenir chaîne localisée pour la langue actuelle et si elle ne le trouve pas, il va l'obtenir en utilisant la langue anglaise.

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

Je voulais ajouter le support pour une langue qui n'est pas officiellement pris en charge par iOS (ne figurant pas dans la section Langue sous Paramètres du système). En suivant le Internationalisation d'Apple Tutorial et quelques conseils ici par Brian Webster et Geon, je suis venu avec ce morceau de code (mettre en 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]));
    }
}

Cela fonctionne bien pour les Storyboard et le code NSLocalizedString. Le code suppose que l'utilisateur aura la possibilité de modifier manuellement la langue dans l'application plus tard.

Bien sûr, ne pas oublier d'ajouter les traductions appropriées Storyboard et traductions Localizable.strings (voir le lien vers la page d'Apple ci-dessus pour savoir comment faire).

Voici une solution décente pour ce problème, et il ne nécessite pas de redémarrage de l'application.

https://github.com/cmaftuleac/BundleLocalization

Cette implémentation fonctionne en modifiant légèrement l'intérieur NSBundle. L'idée est que vous substituez la méthode localizedStringForKey sur l'instance d'objet NSBundle, puis appelez cette méthode sur un ensemble différent avec une autre langue. Simple et élégant entièrement compatible avec tous les types de ressources.

4 rapide, je l'ai résolu sans avoir besoin de redémarrer ou bibliothèques d'utilisation.

Après avoir essayé beaucoup d'options, je trouve cette fonction, où vous passez le stringToLocalize (de Localizable.String, le fichier de chaînes) que vous voulez traduire, et la langue dans laquelle vous voulez traduire, et ce qu'il retourne est la valeur de cette chaîne que vous avez dans le fichier Strings:

    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)
    }

La prise en compte de cette fonction, j'ai créé cette fonction dans un fichier Swift:

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!)!
    }
}

Pour accéder à partir de l'application entière, et dans chaque chaîne du reste de ViewControllers, au lieu de mettre:

NSLocalizedString ("StringToLocalize", comment: “")

Je l'ai remplacé par

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

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

Je ne sais pas si c'est la meilleure façon, mais je l'ai trouvé très simple, et il fonctionne pour moi, je l'espère vous aide!

tout ce que vous faites tous, la meilleure façon est de prendre le short_name pour la langue spécifiée, i.e. .: fr, en, nl, de, il, etc ... et attribuer le même à une valeur globale.

faire une vue sélecteur pour faire apparaître comme un menu déroulant (combinaison d'un bouton clic dont une vue du sélecteur apparaît en bas avec une liste des langues) et sélectionnez la langue que vous désirez. laissez le nom court être stocké en interne. faire un fichier .H + .m du nom LocalisedString.

Définir la valeur globale de short_name égale à la valeur obtenue dans LocalisedString.m Lorsque la langue souhaitée est sélectionnée attribuer le NSBundlePath pour créer projet sous-répertoires pour la langue nécessaire. pour exemple, nl.proj, en.proj.

Lorsque le dossier particulier proj est choisi appeler la chaîne localisée pour la langue respective et changer la langue dynamiquement.

pas de règles cassé.

Pour Swift vous pouvez remplacer le fichier main.swift et définir la chaîne UserDefaults avant vous exécute l'application. De cette façon, vous ne devez pas redémarrer l'application pour voir l'effet désiré.

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))

jumelé ainsi que la suppression de @UIApplicationMain dans votre fichier AppDelegate.swift.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top