En iPhone, NSLocalizedString
devuelve la cadena en el idioma del iPhone. ¿Es posible forzar el NSLocalizedString
uso de un idioma específico para tener la aplicación en un idioma diferente al del dispositivo?
263
En iPhone, NSLocalizedString
devuelve la cadena en el idioma del iPhone. ¿Es posible forzar el NSLocalizedString
uso de un idioma específico para tener la aplicación en un idioma diferente al del dispositivo?
Respuestas:
NSLocalizedString()
(y sus variantes) acceda a la clave "AppleLanguages"NSUserDefaults
para determinar cuáles son las configuraciones del usuario para los idiomas preferidos. Esto devuelve una serie de códigos de idioma, siendo el primero el establecido por el usuario para su teléfono y los siguientes utilizados como retrocesos si un recurso no está disponible en el idioma preferido. (en el escritorio, el usuario puede especificar varios idiomas con un pedido personalizado en Preferencias del sistema)Puede anular la configuración global para su propia aplicación si lo desea utilizando el método setObject: forKey: para configurar su propia lista de idiomas. Esto tendrá prioridad sobre el valor establecido globalmente y se devolverá a cualquier código en su aplicación que esté realizando la localización. El código para esto se vería así:
Esto haría que el alemán sea el idioma preferido para su aplicación, con inglés y francés como respaldo. Debería llamar a esto en algún momento temprano en el inicio de su aplicación. Puede leer más sobre las preferencias de idioma / idioma aquí: Temas de programación de internacionalización: Obtener el idioma y el idioma actuales
fuente
Tuve el mismo problema recientemente y no quería comenzar y parchear todo mi NSLocalizedString ni forzar la aplicación a reiniciarse para que el nuevo idioma funcione. Quería que todo funcionara como está.
Mi solución fue cambiar dinámicamente la clase del paquete principal y cargar el paquete apropiado allí:
Archivo de cabecera
Implementación
Básicamente, cuando su aplicación se inicia y antes de cargar su primer controlador, simplemente llame:
Cuando su usuario cambie su idioma preferido en la pantalla de configuración, simplemente vuelva a llamarlo:
Para restablecer los valores predeterminados del sistema, simplemente pase nil:
Disfrutar...
Para aquellos que necesitan una versión Swift:
fuente
Normalmente hago esto de esta manera, pero DEBES tener todos los archivos de localización en tu proyecto.
fuente
No lo use en iOS 9. Esto devuelve nulo para todas las cadenas pasadas a través de él.
He encontrado otra solución que le permite actualizar las cadenas de idioma, sin reiniciar la aplicación y compatible con cadenas genéricas:
Pon esta macro en el Prefix.pch:
y donde sea que necesite un uso de cadena localizado:
Para configurar el uso del idioma:
Funciona incluso con saltos de idioma consecutivos como:
fuente
Como se dijo anteriormente, solo haz:
Pero para evitar tener que reiniciar la aplicación, coloque la línea en el método principal de
main.m
, justo antesUIApplicationMain
(...).fuente
NSAutoreleasePool * pool ..
filtren algunos objetos que se liberen automáticamente.[[NSBundle mainBundle] URLForResource:withExtension:]
antes.El truco para usar un idioma específico seleccionándolo desde la aplicación es forzar el
NSLocalizedString
uso de un paquete específico dependiendo del idioma seleccionado,Aquí está la publicación que he escrito para esta localización de avance de aprendizaje en aplicaciones ios
y aquí está el código de una localización de avance de aplicación de muestra en aplicaciones ios
fuente
¿Qué opinas sobre esta solución para Swift 3?
Uso simple:
fuente
Como menciona Brian Webster, el idioma debe establecerse "en algún momento temprano en el inicio de su aplicación". Pensé
applicationDidFinishLaunching:
de laAppDelegate
que debería ser un lugar adecuado para hacerlo, ya que es donde hago todos los demás inicialización.Pero como menciona William Denniss, eso parece tener efecto solo después de que se reinicia la aplicación, lo cual es inútil.
Sin embargo, parece funcionar bien si pongo el código en la función principal:
Agradecería cualquier comentario sobre esto.
fuente
[[NSUserDefaults standardUserDefaults] synchronize];
después de llamarsetObject:forKey:
Me gusta más el método de Mauro Delrio. También he agregado lo siguiente en mi Project_Prefix.pch
Entonces, si alguna vez desea usar el método estándar (que usa NSLocalizedString), puede hacer una sustitución rápida de sintaxis en todos los archivos.
fuente
NSLocalizedString()
lee el valor de la claveAppleLanguages
de los valores predeterminados estándar del usuario ([NSUserDefaults standardUserDefaults]
). Utiliza ese valor para elegir una localización adecuada entre todas las localizaciones existentes en tiempo de ejecución. Cuando Apple crea el diccionario predeterminado del usuario en el inicio de la aplicación, busca la clave de idioma (s) preferido en las preferencias del sistema y copia el valor desde allí. Esto también explica, por ejemplo, por qué cambiar la configuración de idioma en OS X no tiene ningún efecto en la ejecución de aplicaciones, solo en las aplicaciones iniciadas a partir de entonces. Una vez copiado, el valor no se actualiza solo porque la configuración cambia. Es por eso que iOS reinicia todas las aplicaciones si cambia el idioma.Sin embargo, todos los valores del diccionario predeterminado del usuario pueden sobrescribirse mediante argumentos de línea de comandos. Ver
NSUserDefaults
documentación en elNSArgumentDomain
. Esto incluso incluye aquellos valores que se cargan desde el archivo de preferencias de la aplicación (.plist). Es realmente bueno saber si desea cambiar un valor solo una vez para la prueba .Entonces, si desea cambiar el idioma solo para las pruebas, probablemente no quiera alterar su código (si olvida eliminar este código más adelante ...), en su lugar, dígale a Xcode que inicie su aplicación con parámetros de línea de comando ( por ejemplo, use la localización en español):
No es necesario tocar su código en absoluto. Simplemente cree diferentes esquemas para diferentes idiomas y puede iniciar rápidamente la aplicación una vez en un idioma y otra en otro simplemente cambiando el esquema.
fuente
Options
como en las versiones más nuevas de Xcode que Apple ofrece que también.Se me ocurrió una solución que te permite usar
NSLocalizedString
. Creo una categoría deNSBundle
llamadaNSBundle+RunTimeLanguage
. La interfaz es así.La implementación es así.
Que simplemente agregar importación
NSBundle+RunTimeLanguage.h
en los archivos que usanNSLocalizedString
.Como puede ver, guardo mi languageCode en una propiedad de
AppDelegate
. Esto podría almacenarse en cualquier lugar que desee.Lo único que no me gusta es una Advertencia que
NSLocalizedString
redefinió el marco. Quizás alguien podría ayudarme a arreglar esta parte.fuente
#undef NSLocalizedString
justo antes#define
para deshabilitar la advertenciaVersión rápida:
fuente
En pocas palabras:
Localiza tu aplicación
Es lo primero que debe hacer es localizar su aplicación con al menos dos idiomas (inglés y francés en este ejemplo).
Anular NSLocalizedString
En su código, en lugar de usar
NSLocalizedString(key, comment)
, use una macroMYLocalizedString(key, comment)
definida como esta:#define MYLocalizedString(key, comment) [[MYLocalizationSystem sharedInstance] localizedStringForKey:(key) value:(comment)];
Este
MYLocalizationSystem
singleton hará lo siguiente:Establecer idioma de usuario
Cuando el usuario cambió el idioma de la aplicación en francés, llame al
[[MYLocalizationSystem sharedInstance] setLanguage:@"fr"];
En este ejemplo, este método establece el paquete localizado en fr.lproj
Devolver cadena localizada
Una vez que haya configurado el paquete localizado, podrá obtener la cadena localizada correcta de él con este método:
Espero que esto te ayudará.
Encontrará más detalles en este artículo de NSWinery.io
fuente
Extensiones Swift 3:
Uso:
fuente
En el archivo .pch para definir:
fuente
Tal vez debería complementar con esto (en el archivo .pch después de #import):
fuente
Solución Swift 3:
Dio algunos ejemplos de códigos de idiomas que se pueden usar. Espero que esto ayude
fuente
Puede crear un subpaquete con el conjunto de cadenas localizadas con las que desea hacer esto y luego usarlo
NSLocalizedStringFromTableInBundle()
para cargarlas. (Supongo que este es un contenido separado de la localización normal de la interfaz de usuario que podría estar haciendo en la aplicación).fuente
para mi caso tengo dos archivos localizados, ja y en
y me gustaría forzarlo a que sea si el idioma preferido en el sistema no es ni ja
voy a editar el archivo main.m
comprobaré si el primer preferido es en o ja, de lo contrario, cambiaré el segundo idioma preferido a en.
fuente
Puedes hacer algo como esto:
fuente
Basado en la respuesta de Tudorizer para cambiar el idioma sin salir o reiniciar la aplicación.
En lugar de una macro, use una clase para acceder al idioma preferido para verificar si hay un código de idioma específico.
A continuación se muestra una clase utilizada para obtener el paquete de idioma actual que funciona para iOS 9:
Use la clase anterior para hacer referencia a un archivo de cadena / imagen / video / etc.
Cambie el idioma en línea como se muestra a continuación o actualice el método "changeCurrentLanguage" en la clase anterior para tomar un parámetro de cadena que haga referencia al nuevo idioma.
fuente
En swift 4, lo resolví sin necesidad de reiniciar o usar bibliotecas.
Después de probar muchas opciones, encontré esta función, donde pasa el stringToLocalize (de Localizable.String, el archivo de cadenas) que desea traducir, y el idioma en el que desea traducirlo, y lo que devuelve es el valor para esa cadena que tienes en el archivo de cadenas:
Teniendo en cuenta esta función, creé esta función en un archivo Swift:
Para acceder desde toda la aplicación, y en cada cadena del resto de ViewControllers, en lugar de poner:
Lo he reemplazado con
No sé si es la mejor manera, pero lo encontré muy simple y funciona para mí, ¡espero que te ayude!
fuente
Esta función intentará obtener una cadena localizada para el idioma actual y, si no se encuentra, la utilizará en inglés.
fuente
Quería agregar soporte para un idioma que no es oficialmente compatible con iOS (no aparece en la sección Idioma en la configuración del sistema). Siguiendo el Tutorial de internacionalización de Apple y algunos consejos aquí de Brian Webster y geon, se me ocurrió este código (póngalo en main.m):
Esto funciona bien tanto para Storyboard como para el código NSLocalizedString. El código supone que el usuario tendrá una opción para cambiar manualmente el idioma dentro de la aplicación más adelante.
Por supuesto, no olvide agregar las traducciones adecuadas de Storyboard y las traducciones de Localizable.strings (consulte el enlace a la página de Apple anterior para saber cómo hacerlo).
fuente
Aquí hay una solución decente para este problema, y no requiere reiniciar la aplicación.
https://github.com/cmaftuleac/BundleLocalization
Esta implementación funciona ajustando dentro de NSBundle. La idea es que anule el método localizedStringForKey en la instancia del objeto NSBundle, y luego llame a este método en un paquete diferente con un idioma diferente. Simple y elegante totalmente compatible con todo tipo de recursos.
fuente
NSString *path = [[NSBundle mainBundle] pathForResource:lang ofType:@"lproj" ];
haga lo que haga, la mejor manera es tomar el nombre_corto para el idioma especificado, es decir: fr, en, nl, de, it, etc. y asignarlo a un valor global.
cree una vista de selector para que aparezca como un menú desplegable (combinación de un botón al hacer clic en el que aparece una vista de selector desde abajo con una lista de idiomas) y seleccione el idioma que desee. deje que el nombre corto se almacene internamente. cree un archivo .h + .m llamado LocalisedString.
Establezca el valor global de short_name para que sea igual al valor obtenido en LocalisedString.m Cuando se selecciona el idioma requerido, asigne NSBundlePath para crear subdirectorios de proyecto para el idioma necesario. por ejemplo, nl.proj, en.proj.
Cuando se selecciona la carpeta de proyecto particular, llame a la cadena localizada para el idioma respectivo y cambie el idioma dinámicamente.
No hay reglas rotas.
fuente
Para Swift, puede anular el
main.swift
archivo y establecer la cadena UserDefaults allí antes de que se ejecute la aplicación. De esta manera, no tiene que reiniciar la aplicación para ver el efecto deseado.emparejado junto con la eliminación de
@UIApplicationMain
en suAppDelegate.swift
archivo.fuente