在iPhone上NSLocalizedString返回iPhone语言的字符串。 是否有可能强制NSLocalizedString使用特定语言来拥有应用程序 用不同的语言吗?
当前回答
对于我的案例,我有两个本地化文件,ja和en
如果系统中首选语言既不是en也不是ja,我希望将其强制为en
我要编辑主体部分。m文件
我会检查第一种首选语言是en还是ja,如果不是,那么我会把第二种首选语言改为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]));
}
}
其他回答
我最近也遇到了同样的问题,我不想启动和修补我的整个NSLocalizedString,也不想强迫应用程序重新启动新的语言工作。我希望一切都能按原样工作。
我的解决方案是动态地改变主bundle的类,并在那里加载适当的bundle:
头文件
@interface NSBundle (Language)
+(void)setLanguage:(NSString*)language;
@end
实现
#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
所以基本上,当你的应用启动时,在你加载你的第一个控制器之前,简单地调用:
[NSBundle setLanguage:@"en"];
当你的用户在你的设置界面中改变他的首选语言时,只需再次调用它:
[NSBundle setLanguage:@"fr"];
要重置回系统默认值,只需传入nil:
[NSBundle setLanguage:nil];
享受……
对于那些需要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)
}
}
正如Brian Webster提到的,语言需要在“应用程序启动初期的某个时候”设置。我认为AppDelegate的applicationDidFinishLaunching:应该是一个合适的地方来做它,因为它是我做所有其他初始化的地方。
但正如威廉·丹尼斯提到的,这似乎只有在应用程序重新启动后才会起作用,这有点没用。
不过,如果我把代码放在main函数中,它似乎工作得很好:
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;
}
如果有任何评论,我将不胜感激。
这里有一个不错的解决方案,它不需要重新启动应用程序。
https://github.com/cmaftuleac/BundleLocalization
这个实现通过在NSBundle内部进行调整来工作。这个想法是你在NSBundle对象的实例上重写localizedStringForKey方法,然后用不同的语言在不同的bundle上调用这个方法。简单而优雅的完全兼容所有类型的资源。
对我来说,测试计划用户,在测试计划的参数中指定- applellanguages (en_BZ)(英语伯利兹语)在启动时传递是有效的。
因为我们使用en_GB和en_BZ, iOS总是首选en_GB。即便如此,当我将设备语言切换到EN,区域切换到BZ,以及在测试计划应用程序语言和应用程序区域设置中设置这些值时。除了上面的老方法,什么都没用:)
我最喜欢Mauro Delrio的方法。 我还在我的Project_Prefix.pch中添加了以下内容
#import "Language.h"
#define MyLocalizedString(key, alt) [Language get:key alter:alt]
如果你想使用标准方法(使用NSLocalizedString)你可以在所有文件中做一个快速的语法替换。
推荐文章
- 如何删除默认的导航栏空间在SwiftUI导航视图
- 为什么Chrome浏览器不正确地确定页面是在不同的语言,并提供翻译?
- 如何在iOS中使用Swift编程segue
- Swift -整数转换为小时/分钟/秒
- Swift:声明一个空字典
- 为什么ARC仍然需要@autoreleasepool ?
- 在成功提交我的应用程序后,“太多符号文件”
- 首先添加一个UIView,甚至是导航栏
- 我如何改变UIButton标题颜色?
- 在Swift中如何调用GCD主线程上的参数方法?
- NSLayoutConstraints是可动画的吗?
- iOS -构建失败,CocoaPods无法找到头文件
- Xcode 4挂在“附加到(应用程序名称)”
- CFNetwork SSLHandshake iOS 9失败
- 请求失败:不可接受的内容类型:文本/html使用AFNetworking 2.0