J'ai eu le même problème récemment et je ne voulais pas recommencer et rafistoler tout mon NSLocalizedString ni obliger l'application à redémarrer pour que la nouvelle langue fonctionne. Je voulais que tout fonctionne tel quel.
Ma solution était de changer dynamiquement la classe du bundle principal et d'y charger le bundle 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, en gros, lorsque votre application démarre et avant de charger votre premier contrôleur, appelez simplement :
[NSBundle setLanguage:@"en"];
Lorsque votre utilisateur change sa langue préférée dans votre écran de paramétrage, il suffit de le rappeler :
[NSBundle setLanguage:@"fr"];
Pour revenir aux valeurs par défaut du système, passez simplement nil :
[NSBundle setLanguage:nil];
Profitez-en...
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)
}
}
0 votes
Veuillez consulter ce : stackoverflow.com/a/48187049/6665075 Fonctionne comme un charme