Jak zmusić NSLocalizedString do używania określonego języka

Na iPhonie NSLocalizedString zwraca ciąg znaków w języku iPhone ' a. Czy można wymusić NSLocalizedString użycie określonego języka, aby mieć aplikację w innym języku niż urządzenie ?

Author: TheNeil, 2009-11-03

27 answers

NSLocalizedString() (i ich warianty) uzyskaj dostęp do klucza "AppleLanguages" w NSUserDefaults, aby określić ustawienia użytkownika dla preferowanych języków. Zwraca tablicę kodów językowych, z których pierwszy to ten ustawiony przez użytkownika dla telefonu, a kolejne używane jako zapasowe, jeśli zasób nie jest dostępny w preferowanym języku. (na pulpicie użytkownik może określić wiele języków za pomocą niestandardowego zamówienia w Preferencjach systemowych)

Możesz nadpisać globalną ustawienie dla własnej aplikacji, Jeśli chcesz, używając metody setObject: forKey:, aby ustawić własną listę języków. Będzie to miało pierwszeństwo przed globalnie ustawioną wartością i zostanie zwrócone do dowolnego kodu w aplikacji, która wykonuje lokalizację. Kod na to wygląda mniej więcej tak:

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

To uczyniłoby język niemiecki preferowanym dla Twojej aplikacji, z angielskim i francuskim jako alternatywą. Powinieneś zadzwonić do tego na początku uruchamiania aplikacji. Możesz przeczytać więcej o preferencjach językowych/locale tutaj: tematy programowania internacjonalizacji: pobieranie bieżącego języka i Locale

 263
Author: Brian Webster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-20 06:01:24

Ostatnio miałem ten sam problem i nie chciałem uruchamiać i łatać całegoNSLocalizedString ani zmuszać aplikacji do ponownego uruchomienia, aby nowy język działał. Chciałem, żeby wszystko działało tak, jak jest.

Moim rozwiązaniem była dynamiczna zmiana klasy pakietu głównego i załadowanie tam odpowiedniego pakietu:

Plik nagłówkowy

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

Realizacja

#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

Więc po uruchomieniu aplikacji i przed załadowaniem pierwszego kontrolera, po prostu wywołanie:

[NSBundle setLanguage:@"en"];

Gdy użytkownik zmieni preferowany język na ekranie ustawień, po prostu zadzwoń do niego ponownie:

[NSBundle setLanguage:@"fr"];

Aby zresetować z powrotem do ustawień domyślnych systemu, po prostu podaj nil:

[NSBundle setLanguage:nil];
Smacznego...

Dla tych, którzy potrzebują wersji 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)
    }
}
 147
Author: Gilad Novik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-19 16:41:26

Zazwyczaj robię to w ten sposób, ale musisz mieć wszystkie pliki lokalizacyjne w swoim projekcie.

@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
 137
Author: Mauro Delrio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-12 08:03:38

Nie używaj w systemie iOS 9. Zwraca nil Dla wszystkich łańcuchów przechodzących przez niego.

Znalazłem inne rozwiązanie, które pozwala na aktualizację ciągów językowych, bez ponownego uruchamiania aplikacji i kompatybilny z genstrings:

Umieść to makro w prefiksie.pch:

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

I tam, gdzie potrzebujesz zlokalizowanego ciągu użyj:

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

Aby ustawić język użyj:

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

Działa nawet z kolejnymi skaczącymi językami jak:

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, @""));
 41
Author: Tudor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-14 17:00:56

Jak powiedziałem wcześniej, po prostu zrób:

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

Ale aby uniknąć konieczności ponownego uruchamiania aplikacji, umieść linię w głównej metodzie main.m, tuż przed UIApplicationMain (...).

 32
Author: Frédéric Feytons,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-01 05:19:52

Sztuczka, aby użyć określonego języka, wybierając go z aplikacji, polega na wymusić NSLocalizedString użycie określonego pakietu w zależności od wybranego języka,

Oto post, który napisałem do tego Nauka zaawansowanej lokalizacji w aplikacjach na ios

A oto kod jednej przykładowej aplikacji zaawansowana lokalizacja w aplikacjach na ios

 32
Author: object2.0,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-19 13:26:36

Co sądzicie o tym rozwiązaniu dla 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)
    }
}

Proste użycie:

"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.
 15
Author: Bartłomiej Semańczyk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-13 15:05:38

Jak wspomina Brian Webster, język musi być ustawiony "kiedyś na początku uruchamiania aplikacji". Pomyślałem, że applicationDidFinishLaunching: z AppDelegate powinno być odpowiednie miejsce, aby to zrobić, ponieważ to tam robię wszystkie inne inicjalizacji.

Ale jak wspomina William Denniss, wydaje się to mieć wpływ tylko po aplikacja jest ponownie uruchomiona, co jest trochę bezużyteczne.

Wydaje się, że działa dobrze, jeśli umieszczę kod w głównej funkcji, chociaż:

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

Będę wdzięczny za wszelkie komentarze na to.

 14
Author: geon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-01 05:20:32

NSLocalizedString() odczytuje wartość klucza AppleLanguages ze standardowej domyślnej wartości użytkownika ([NSUserDefaults standardUserDefaults]). Używa tej wartości, aby wybrać odpowiednią lokalizację spośród wszystkich istniejących lokalizacji w czasie wykonywania. Gdy Apple tworzy słownik domyślnych użytkowników podczas uruchamiania aplikacji, wyszukuje klucz preferowanych języków w Preferencjach systemowych i skopiuje stamtąd wartość. Wyjaśnia to również na przykład, dlaczego zmiana ustawień językowych w systemie OS X nie ma wpływu na uruchomione aplikacje, tylko na aplikacje uruchomione później. Raz skopiowane, wartość nie jest aktualizowana tylko dlatego, że Ustawienia się zmieniają. Dlatego iOS uruchamia ponownie wszystkie aplikacje, jeśli zmienisz język.

Jednakże wszystkie wartości słownika domyślnego użytkownika mogą być nadpisane argumentami wiersza poleceń. Zobacz NSUserDefaults dokumentację na NSArgumentDomain. Obejmuje to nawet te wartości, które są ładowane z preferencji aplikacji (.plist) plik. To naprawdę dobrze wiedzieć , jeśli chcesz zmienić wartość tylko raz dla testów .

Więc jeśli chcesz Zmień język tylko do testów, prawdopodobnie nie chcesz zmieniać kodu (jeśli później zapomnisz usunąć ten kod ...Xcode uruchamia aplikację z parametrami wiersza poleceń (np. Użyj lokalizacji w języku hiszpańskim):

Tutaj wpisz opis obrazka

Nie musisz dotykać kodu. Wystarczy utworzyć różne schematy dla różnych języków i można szybko uruchomić aplikację raz w jednym języku, a raz w innym, po prostu przełączając schemat.
 12
Author: Mecki,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-10 10:28:02

Najbardziej podoba mi się metoda Mauro Delrio. Dodałem również następujące elementy w moim Project_Prefix.pch

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

Więc jeśli kiedykolwiek chcesz użyć standardowej metody (która używa NSLocalizedString) możesz dokonać szybkiego zastępowania składni we wszystkich plikach.

 11
Author: dnaxxx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-27 12:38:26

Wymyśliłem rozwiązanie, które pozwala na użycie NSLocalizedString. Tworzę kategorię NSBundle wywołania NSBundle+RunTimeLanguage. Interfejs jest taki.

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

Implementacja wygląda tak.

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

Niż tylko dodać import NSBundle+RunTimeLanguage.h do plików, które używają NSLocalizedString.

Jak widzisz przechowuję swój kod językowy w właściwości AppDelegate. To może być przechowywane w dowolnym miejscu.

Nie podoba mi się tylko ostrzeżenie, które marco przedefiniował. Może ktoś mógłby pomóc ja to naprawię.
 10
Author: qman64,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-30 19:14:52

Wersja Swift:

NSUserDefaults.standardUserDefaults().setObject(["fr"], forKey: "AppleLanguages")
NSUserDefaults.standardUserDefaults().synchronize()
 9
Author: daaniaal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-27 15:47:14

W skrócie:

Zlokalizuj swoją aplikację

Pierwszą rzeczą, którą musisz zrobić, jest zlokalizowanie aplikacji w co najmniej dwóch językach (angielski i francuski w tym przykładzie).

Override NSLocalizedString

W kodzie zamiast NSLocalizedString(key, comment) Użyj makra MYLocalizedString(key, comment) zdefiniowanego w ten sposób : #define MYLocalizedString(key, comment) [[MYLocalizationSystem sharedInstance] localizedStringForKey:(key) value:(comment)];

This MYLocalizationSystem singleton will:

  • Ustaw langage ustawiając prawo zlokalizowane NSBundle użytkownik pyta o
  • zwraca zlokalizowane NSString zgodnie z tym wcześniej ustawionym językiem

Ustaw język użytkownika

Gdy użytkownik zmienił język aplikacji w języku francuskim, wywołaj [[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];
}

W tym przykładzie ta metoda ustawia localized bundle na fr.lproj

Return localized string

Po ustawieniu zlokalizowanego pakietu, będziesz mógł uzyskać od niego właściwy zlokalizowany ciąg znaków za pomocą tej metody:

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

Mam nadzieję, że to pomoże ty.

Więcej szczegółów znajdziesz w tym artykule z NSWinery.io

 8
Author: user3465357,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-23 10:49:52

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

Użycie:

Locale.preferredLanguage = "uk"

label.text = "localizedKey".localized
 7
Author: ChikabuZ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-05 16:24:52

W swift 4 rozwiązałem go bez potrzeby ponownego uruchamiania lub używania bibliotek.

Po wypróbowaniu wielu opcji znalazłem tę funkcję, w której przekazujesz stringToLocalize (z Localizable.String, plik strings), który chcesz przetłumaczyć, i język, w którym chcesz go przetłumaczyć, a to, co zwraca, to wartość tego ciągu, który masz w pliku 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)
    }

Biorąc pod uwagę tę funkcję, utworzyłem tę funkcję w pliku 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!)!
    }
}

To dostęp z całej aplikacji i w każdym ciągu pozostałych kontrolerów ViewControllers, zamiast umieszczać:

NSLocalizedString ("StringToLocalize", comment: “")

Zastąpiłem go

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

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

Nie wiem, czy to najlepszy sposób, ale uważam, że jest to bardzo proste i działa dla mnie, mam nadzieję, że ci pomoże!

 6
Author: ainareta685,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-05-13 08:55:12

W pliku .pch do zdefiniowania:

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


#define NSLocalizedString(str,nil) NSLocalizedStringFromTableInBundle(str, nil, currentLanguageBundle, @"")
 5
Author: MrPiliffo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-19 13:26:25

Może powinieneś uzupełnić o to (on .plik pch po # 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]
 4
Author: D33pN16h7,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-12 07:48:24

Swift 3 Rozwiązanie:

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

Podał kilka przykładów kodów językowych, które można wykorzystać. Mam nadzieję, że to pomoże

 4
Author: Jeremy Bader,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-23 15:17:29

Możesz zbudować podpakietę z zestawem zlokalizowanych ciągów, z którymi chcesz to zrobić, a następnie użyć NSLocalizedStringFromTableInBundle() żeby je załadować. (Zakładam, że jest to zawartość oddzielona od normalnej lokalizacji interfejsu użytkownika, którą możesz robić w aplikacji.)

 3
Author: Sixten Otto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-03 19:51:36

W moim przypadku mam dwa pliki zlokalizowane, ja i en

I chciałbym zmusić go do en, jeśli preferowany język w systemie ani en, ani ja

Zamierzam edytować główny.m file

Sprawdzę, czy pierwszym preferowanym jest en Czy ja , jeśli nie, to zmienię drugi preferowany język NA 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
Author: chings228,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-02 08:40:51

Możesz zrobić coś takiego:

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


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

NSLocalizedStringFromTableInBundle(@"House", nil, spanishBundle, nil):
 2
Author: JERC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-17 20:59:51

Oto przyzwoite rozwiązanie tego problemu i nie wymaga ponownego uruchomienia aplikacji.

Https://github.com/cmaftuleac/BundleLocalization

Ta implementacja działa poprzez podkręcanie wewnątrz NSBundle. Chodzi o to, że nadpisujesz metodę localizedStringForKey na instancji obiektu NSBundle, a następnie wywołujesz tę metodę na innym pakiecie z innym językiem. Prosty i elegancki w pełni kompatybilny ze wszystkimi rodzajami zasobów.

 2
Author: Corneliu Maftuleac,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-16 19:24:15

na podstawie Odpowiedzi na zmianę języka Bez opuszczania lub restartowania aplikacji.

Zamiast makra, Użyj klasy, aby uzyskać dostęp do preferowanego języka, aby sprawdzić, czy istnieje określony kod języka.

Poniżej znajduje się Klasa używana do uzyskania bieżącego pakietu językowego, który działa na 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

Użyj powyższej klasy, aby odwołać się do pliku string / image / video / 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")

Zmień język in-line jak poniżej lub zaktualizuj metodę "changeCurrentLanguage" w powyższej klasie, aby pobrać parametr string odwołujący się do nowego języka.

[[NSUserDefaults standardUserDefaults] setObject:@[@"es"] forKey:@"AppleLanguages"];
 2
Author: Antonioni,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-28 21:40:08

Ta funkcja spróbuje uzyskać zlokalizowany ciąg znaków dla bieżącego języka i jeśli nie zostanie znaleziony, otrzyma go w języku angielskim.

- (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;
}
 1
Author: Cherpak Evgeny,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-17 08:41:07

Chciałem dodać obsługę języka, który nie jest oficjalnie obsługiwany przez iOS(nie jest wymieniony w sekcji Język w ustawieniach systemu). Idąc za internacjonalizacji Apple Tutorial i kilka wskazówek tutaj Brian Webster i geon, wymyśliłem ten kawałek kodu (umieścić go w 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]));
    }
}

To działa dobrze zarówno dla Storyboard i nslocalizedstring kodu. Kod zakłada, że użytkownik będzie miał możliwość ręcznej zmiany języka wewnątrz aplikacji później.

Z oczywiście, nie zapomnij dodać odpowiednie tłumaczenia Storyboard i Localizable.tłumaczenia ciągów (zobacz link do strony Apple powyżej, aby to zrobić).

 1
Author: frin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-09 19:23:34

Cokolwiek robicie, najlepszym sposobem jest wzięcie skrótu dla podanego języka, tj.: fr, en, nl, de, it, itp... i przypisać to samo do wartości globalnej.

Wykonaj widok selektora, aby wyskakiwał jak rozwijane menu (kombinacja przycisku, po kliknięciu którego widok selektora pojawia się poniżej z listą języków)i wybierz język, który chcesz. niech nazwa skrócona będzie przechowywana wewnętrznie. zrób .h + .m plik o nazwie LocalisedString.

Ustaw globalną wartość short_name być równe otrzymanej wartości w LocalisedString.na Po wybraniu wymaganego języka Przypisz NSBundlePath do utworzenia podkatalogów projektu dla potrzebnego języka. dla np. nl.proj, en.proj.

Po wybraniu danego folderu proj wywołaj zlokalizowany ciąg znaków dla danego języka i zmieniaj go dynamicznie.

Żadne zasady nie zostały złamane.

 0
Author: Abhijeet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-12 11:17:35

Dla Swift możesz nadpisać plik main.swift i ustawić tam ciąg UserDefaults przed uruchomieniem aplikacji. W ten sposób nie musisz ponownie uruchamiać aplikacji, aby zobaczyć pożądany efekt.

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

W połączeniu z usunięciem @UIApplicationMain w pliku AppDelegate.swift.

 0
Author: Andreas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-07-01 11:00:52