Meine Frage:
Wie kann meine iPhone-App dem iOS mitteilen, dass der Benutzer in den App-Einstellungen eine Sprache ausgewählt hat, die sich von der in den allgemeinen Einstellungen festgelegten Sprache unterscheidet?
Andere Formulierung der gleichen Frage:
Wie kann ich dem System mitteilen, dass NSLocalizedString (@"text", @"comment");
nicht auf die systemweit ausgewählte Sprache, sondern auf die in der App ausgewählte Sprache zugegriffen werden soll?
Hintergrund, Beispiel:
Bitte nehmen Sie diese Situation als Beispiel: Ein Sohn deutscher Einwanderer lebt im Nordosten Frankreichs neben Luxemburg und Deutschland. Seine Muttersprache ist Französisch, daher hat er die Sprache der Benutzeroberfläche seines iPhones auf Französisch eingestellt (Einstellungen -> Allgemein -> International -> Sprache -> Français). Aufgrund seines kulturellen Hintergrunds und der zweisprachigen Region, in der er lebt, spricht er auch sehr gut Deutsch. Aber er spricht keine zehn Wörter Englisch. Auf einem iPhone (und auch auf einem iPad) hat er keine Möglichkeit, eine zweite Sprache auszuwählen, sodass das Telefon nur weiß, dass er Französisch spricht. Es hat keine Kenntnisse über die Fähigkeiten des Benutzers in anderen Sprachen.
Jetzt kommt meine App: Ich habe sie in Englisch und Deutsch entwickelt (Deutsch ist meine Muttersprache und Englisch ist Standardsprache in der IT). Ich habe es nach allen Regeln und Best Practices für mehrsprachige iOS-Apps entwickelt. "Erste" Sprache (Standardsprache) meiner App ist Englisch.
Das heisst:
Wenn jemand in seinen Einstellungen Englisch oder Deutsch ausgewählt hat, verwendet die Benutzeroberfläche der Apps automatisch die ausgewählte Sprache. Der Benutzer wird nicht einmal bemerken, dass andere Sprachen verfügbar sind.
Wenn er jedoch in den allgemeinen Einstellungen eine andere Sprache (wie Chinesisch, Polnisch oder Französisch) ausgewählt hat, erhält er die Standardsprache der Apps, in meinem Fall Englisch. Aber für meinen französisch-deutschen Freund ist dies nicht die beste Wahl. Er möchte die vorhandene deutsche Version verwenden, aber es scheint keine Möglichkeit zu geben, den Benutzer diese Version auswählen zu lassen.
Das Hinzufügen einer französischen Übersetzung würde das Problem für unseren französisch-deutschen Freund lösen, aber nicht für Leute, die zwei andere Sprachen sprechen (wie Italienisch und Deutsch), und ich kann meine App nicht mit allen auf diesem Planeten gesprochenen Sprachen unterstützen. Das Einstellen der Standardsprache auf Deutsch ist ebenfalls nicht optimal, da dies das gleiche Problem für Personen aufwerfen würde, die Französisch (eine Muttersprache) und Englisch (als Zweitsprache) sprechen.
Daher denke ich, dass meine App die Möglichkeit haben muss, manuell eine Sprache auszuwählen, die sich von der vorgewählten Sprache unterscheidet. Das Hinzufügen einer Sprachauswahl zum App-Einstellungsfeld ist nicht das Problem. Aber wie kann ich dem System mitteilen, dass NSLocalizedString (@"text", @"comment");
es nicht auf die systemweit ausgewählte Sprache zugreifen soll, sondern auf die in der App ausgewählte Sprache?
quelle
Antworten:
In der Zwischenzeit habe ich selbst eine Lösung für mein Problem gefunden:
Ich habe eine neue Klasse "LocalizeHelper" erstellt:
Header LocalizeHelper.h
//LocalizeHelper.h #import <Foundation/Foundation.h> // some macros (optional, but makes life easy) // Use "LocalizedString(key)" the same way you would use "NSLocalizedString(key,comment)" #define LocalizedString(key) [[LocalizeHelper sharedLocalSystem] localizedStringForKey:(key)] // "language" can be (for american english): "en", "en-US", "english". Analogous for other languages. #define LocalizationSetLanguage(language) [[LocalizeHelper sharedLocalSystem] setLanguage:(language)] @interface LocalizeHelper : NSObject // a singleton: + (LocalizeHelper*) sharedLocalSystem; // this gets the string localized: - (NSString*) localizedStringForKey:(NSString*) key; //set a new language: - (void) setLanguage:(NSString*) lang; @end
iMplementation LocalizeHelper.m
// LocalizeHelper.m #import "LocalizeHelper.h" // Singleton static LocalizeHelper* SingleLocalSystem = nil; // my Bundle (not the main bundle!) static NSBundle* myBundle = nil; @implementation LocalizeHelper //------------------------------------------------------------- // allways return the same singleton //------------------------------------------------------------- + (LocalizeHelper*) sharedLocalSystem { // lazy instantiation if (SingleLocalSystem == nil) { SingleLocalSystem = [[LocalizeHelper alloc] init]; } return SingleLocalSystem; } //------------------------------------------------------------- // initiating //------------------------------------------------------------- - (id) init { self = [super init]; if (self) { // use systems main bundle as default bundle myBundle = [NSBundle mainBundle]; } return self; } //------------------------------------------------------------- // translate a string //------------------------------------------------------------- // you can use this macro: // LocalizedString(@"Text"); - (NSString*) localizedStringForKey:(NSString*) key { // this is almost exactly what is done when calling the macro NSLocalizedString(@"Text",@"comment") // the difference is: here we do not use the systems main bundle, but a bundle // we selected manually before (see "setLanguage") return [myBundle localizedStringForKey:key value:@"" table:nil]; } //------------------------------------------------------------- // set a new language //------------------------------------------------------------- // you can use this macro: // LocalizationSetLanguage(@"German") or LocalizationSetLanguage(@"de"); - (void) setLanguage:(NSString*) lang { // path to this languages bundle NSString *path = [[NSBundle mainBundle] pathForResource:lang ofType:@"lproj" ]; if (path == nil) { // there is no bundle for that language // use main bundle instead myBundle = [NSBundle mainBundle]; } else { // use this bundle as my bundle from now on: myBundle = [NSBundle bundleWithPath:path]; // to be absolutely shure (this is probably unnecessary): if (myBundle == nil) { myBundle = [NSBundle mainBundle]; } } } @end
Für jede Sprache, die Sie unterstützen möchten, benötigen Sie eine Datei mit dem Namen
Localizable.strings
. Dies funktioniert genau wie in der Apples-Dokumentation zur Lokalisierung beschrieben. Der einzige Unterschied: Jetzt können Sie sogar Sprachen wie Hindi oder Esperanto verwenden, die von Apple nicht unterstützt werden.Um Ihnen ein Beispiel zu geben, hier sind die ersten Zeilen meiner englischen und deutschen Versionen von Localizable.strings:
Englisch
/* English - English */ /* for debugging */ "languageOfBundle" = "English - English"; /* Header-Title of the Table displaying all lists and projects */ "summary" = "Summary"; /* Section-Titles in table "summary" */ "help" = "Help"; "lists" = "Lists"; "projects" = "Projects"; "listTemplates" = "List Templates"; "projectTemplates" = "Project Templates";
Deutsche
/* German - Deutsch */ /* for debugging */ "languageOfBundle" = "German - Deutsch"; /* Header-Title of the Table displaying all lists and projects */ "summary" = "Überblick"; /* Section-Titles in table "summary" */ "help" = "Hilfe"; "lists" = "Listen"; "projects" = "Projekte"; "listTemplates" = "Vorlagen für Listen"; "projectTemplates" = "Vorlagen für Projekte";
Um die Lokalisierung verwenden zu können, müssen Sie einige Einstellungsroutinen in Ihrer App haben und in der Sprachauswahl das Makro aufrufen:
LocalizationSetLanguage(selectedLanguage);
Danach müssen Sie sicherstellen, dass alles, was in der alten Sprache angezeigt wurde, jetzt in der neuen Sprache neu gezeichnet wird (versteckte Texte müssen neu gezeichnet werden, sobald sie wieder sichtbar werden).
Um lokalisierte Texte für jede Situation verfügbar zu haben, müssen Sie NIEMALS feste Texte in die Objekttitel schreiben. Verwenden Sie IMMER das Makro
LocalizedString(keyword)
.nicht:
cell.textLabel.text = @"nice title";
machen:
cell.textLabel.text = LocalizedString(@"nice title");
und habe einen "schönen Titel" -Eintrag in jeder Version von Localizable.strings!
quelle
Fügen Sie dem Bildschirm einfach Folgendes mit Sprachauswahl hinzu:
NSString *tempValue = //user chosen language. Can be picker view/button/segmented control/whatever. Just get the text out of it NSString *currentLanguage = @""; if ([tempValue rangeOfString:NSLocalizedString(@"English", nil)].location != NSNotFound) { currentLanguage = @"en"; } else if ([tempValue rangeOfString:NSLocalizedString(@"German", nil)].location != NSNotFound) { currentLanguage = @"de"; } else if ([tempValue rangeOfString:NSLocalizedString(@"Russian", nil)].location != NSNotFound) { currentLanguage = @"ru"; } [[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:currentLanguage, nil] forKey:@"AppleLanguages"]; [[NSUserDefaults standardUserDefaults]synchronize];
Bitten Sie sie dann, die App neu zu starten, und die App wird in einer anderen Sprache angezeigt.
Ich hoffe es hilft
quelle
Application does not run in background
sie Ihrerinfo.plist
Datei hinzufügen . Jedes Mal, wenn Sie in Ihrer App auf die Home-Schaltfläche klicken, wird Ihre App geschlossen. Markieren Sie die Antwort als richtig, um andere Benutzer zu ermutigen, Ihre Fragen in Zukunft zu beantworten.Hier ist eine gebrauchsfertige und schrittweise Anleitung zur Verwendung des Novarg-Ansatzes in Swift 3 :
Schritt 1: Implementieren Sie eine Sprachauswahl
Wie dies am besten funktioniert, liegt bei Ihnen und hängt vom Projekt ab. Aber benutze
Bundle.main.localizations.filter({ $0 != "Base" }) // => ["en", "de", "tr"]
um programmgesteuert eine Liste aller unterstützten Sprachcodes für Gebietsschemas zu erhalten . Auch können Sie verwenden
Locale.current.localizedString(forLanguageCode: "en") // replace "en" with your variable
um den Sprachnamen in der aktuellen Sprache der Apps anzuzeigen .
Als vollständiges Beispiel können Sie ein Popover-Aktionsblatt anzeigen, nachdem Sie auf eine Schaltfläche wie die folgende geklickt haben:
@IBOutlet var changeLanguageButton: UIButton! @IBAction func didPressChangeLanguageButton() { let message = "Change language of this app including its content." let sheetCtrl = UIAlertController(title: "Choose language", message: message, preferredStyle: .actionSheet) for languageCode in Bundle.main.localizations.filter({ $0 != "Base" }) { let langName = Locale.current.localizedString(forLanguageCode: languageCode) let action = UIAlertAction(title: langName, style: .default) { _ in self.changeToLanguage(languageCode) // see step #2 } sheetCtrl.addAction(action) } let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil) sheetCtrl.addAction(cancelAction) sheetCtrl.popoverPresentationController?.sourceView = self.view sheetCtrl.popoverPresentationController?.sourceRect = self.changeLanguageButton.frame present(sheetCtrl, animated: true, completion: nil) }
Schritt 2: Erklären Sie dem Benutzer, was zu tun ist. + Ändern Sie die Sprache beim Neustart
Möglicherweise haben Sie bemerkt, dass der Code in Schritt 1 eine Methode mit dem Namen aufruft
changeToLanguage(langCode:)
. Dies sollten Sie auch tun, wenn der Benutzer eine neue Sprache zum Ändern auswählt, unabhängig davon, wie Sie Ihre Auswahl gestaltet haben. Hier ist die Implementierung , kopieren Sie sie einfach in Ihr Projekt:private func changeToLanguage(_ langCode: String) { if Bundle.main.preferredLocalizations.first != langCode { let message = "In order to change the language, the App must be closed and reopened by you." let confirmAlertCtrl = UIAlertController(title: "App restart required", message: message, preferredStyle: .alert) let confirmAction = UIAlertAction(title: "Close now", style: .destructive) { _ in UserDefaults.standard.set([langCode], forKey: "AppleLanguages") UserDefaults.standard.synchronize() exit(EXIT_SUCCESS) } confirmAlertCtrl.addAction(confirmAction) let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil) confirmAlertCtrl.addAction(cancelAction) present(confirmAlertCtrl, animated: true, completion: nil) } }
Dadurch wird der Benutzer gefragt und informiert, ob und wie er die Änderung vornehmen möchte. Außerdem wird die Sprache der Apps beim nächsten Start wie folgt festgelegt:
UserDefaults.standard.set([langCode], forKey: "AppleLanguages") UserDefaults.standard.synchronize() // required on real device
Schritt 3 (optional): Lokalisieren Sie die Zeichenfolgen
Möglicherweise möchten Sie die Zeichenfolgen wie "Jetzt schließen" mithilfe des
NSLocalizedString
Makros (oder einer anderen erweiterten Methode) lokalisieren .Beispiel aus der realen Welt
Ich verwende genau diese Implementierung in einer App für iOS 10 und kann bestätigen, dass sie sowohl auf dem Simulator als auch auf dem Gerät für mich funktioniert . Die App ist eigentlich Open Source , so dass Sie den obigen Code verteilt in verschiedene Klassen finden hier .
quelle
locale
Satz irgendwo in der Anfrage. Wenn Sie keinen Zugriff auf den Server haben, möchten Sie möglicherweise einen maschinellen Übersetzungsdienst wie Google Translate verwenden - aber die Ergebnisse sind möglicherweise nicht die besten ...Ab iOS 13 gibt es jetzt die Möglichkeit, für jede App eine eigene Sprache festzulegen, die von iOS selbst unterstützt wird. Öffnen Sie in der Apple Settings-App die Einstellungen der jeweiligen App und wählen Sie die Sprache unter "Bevorzugte Sprache" aus. Sie können aus den von der App unterstützten Sprachen auswählen.
quelle
Meine Antwort kann eine Frage der Präferenz sein, da ich die manuelle Sprachauswahl in der App verachten würde: Sie müssen alle vom System bereitgestellten Schaltflächen überschreiben und sicherstellen, dass Sie sie nicht verwenden. Es fügt auch eine weitere Komplexitätsebene hinzu und kann den Benutzer zu Verwirrung führen.
Da dies jedoch eine Antwort sein muss, denke ich, dass Ihr Anwendungsfall gelöst ist, ohne die Sprachauswahl zu hacken.
In den iOS-Einstellungen können Sie zusätzliche Sprachen festlegen:
Ihr Beispielsohn von Einwanderern hätte Französisch als Hauptsprache und Deutsch als zusätzliche Sprache festlegen können.
Wenn Ihre App dann auf Englisch und Deutsch lokalisiert ist, wählt das iPhone dieses jungen Mannes deutsche Ressourcen aus.
Würde das das Problem lösen?
quelle
Localize-Swift - Schnelle, freundliche Lokalisierung und i18n mit In-App-Sprachumschaltung
quelle
Es ist sehr einfach und leicht, die Sprache manuell zu ändern. Zuerst müssen Sie Ihre App lokalisieren, dann können Sie den folgenden Code verwenden, um die Sprache in Ihrer App manuell zu ändern.
UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"App restart required", @"App restart required") message:NSLocalizedString(@"In order to change the language, the App must be closed and reopened by you.", @"In order to change the language, the App must be closed and reopened by you.") preferredStyle:UIAlertControllerStyleActionSheet]; [actionSheet addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", @"Cancel") style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) { [self dismissViewControllerAnimated:YES completion:^{ }]; }]]; [actionSheet addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Restart", @"Restart") style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) { [[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:@"ar", nil] forKey:@"AppleLanguages"]; [[NSUserDefaults standardUserDefaults]synchronize]; exit(EXIT_SUCCESS); }]]; [self presentViewController:actionSheet animated:YES completion:nil]; }
quelle
Ich hatte ein ähnliches Problem in meinem aktuellen Arbeitsprojekt. Ich fand einen einfachen Weg, dies zu tun, und musste ihn meinen Partnern erklären, um die Lösung zu besprechen. Ich habe eine einfache App mit 2 Schaltflächen (Englisch || Spanisch) erstellt, um die Sprache in der App auszuwählen. Der Code befindet sich in Objective-C (da sich unsere aktuelle App in Objective-C befindet). Hier ist der Code: https: // bitbucket .org / gastonmontes / gmlanguageselectiondemo
quelle