您想从应用程序 UI 设置应用程序的语言,而忽略设备上的用户首选项。这很不寻常,但是你去...
首先将所有语言字符串写在这样的目录结构中:
i18n/en.lproj/Localizable.strings
i18n/ar.lproj/Localizable.strings
为每种支持的其他语言创建一个具有相应两个字母代码的附加目录。
如果文件被识别为 i18n 资源,它们将如下所示:
文件将具有以下格式的 key=value:
"button.back" = "ظهر";
在您的代码中,将任何可本地化的字符串替换为该键。例子:
[self.stateBtn setTitle:localize(@"button.back") forState:UIControlStateNormal];
通常你会使用NSLocalizedString(@"key",@"fallback")
,但由于你想忽略 iPhone 设置,我在localize(@"key")
上面写了一个宏,它具有以下实现:
本地化.h
#ifndef localize
#define localize(key) [[Localization sharedInstance] localizedStringForKey:key]
#endif
@interface Localization : NSObject
@property (nonatomic, retain) NSBundle* fallbackBundle;
@property (nonatomic, retain) NSBundle* preferredBundle;
@property (nonatomic, copy) NSString* fallbackLanguage;
@property (nonatomic, copy) NSString* preferredLanguage;
-(NSString*) localizedStringForKey:(NSString*)key;
-(NSString*) pathForFilename:(NSString*)filename type:(NSString*)type;
+(Localization*)sharedInstance;
@end
本地化.m
#import "Localization.h"
@implementation Localization
+(Localization *)sharedInstance
{
static dispatch_once_t pred;
static Localization *shared = nil;
dispatch_once(&pred, ^{
shared = [[Localization alloc] init];
[shared setPreferred:@"en" fallback:@"ar"];
});
return shared;
}
-(void) setPreferred:(NSString*)preferred fallback:(NSString*)fallback
{
self.fallbackLanguage = fallback;
self.preferredLanguage = preferred;
NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"Localizable" ofType:@"strings" inDirectory:nil forLocalization:self.fallbackLanguage];
self.fallbackBundle = [[NSBundle alloc] initWithPath:[bundlePath stringByDeletingLastPathComponent]];
bundlePath = [[NSBundle mainBundle] pathForResource:@"Localizable" ofType:@"strings" inDirectory:nil forLocalization:self.preferredLanguage];
self.preferredBundle = [[NSBundle alloc] initWithPath:[bundlePath stringByDeletingLastPathComponent]];
}
-(NSString*) pathForFilename:(NSString*)filename type:(NSString*)type
{
NSString *path = [self.preferredBundle pathForResource:filename ofType:type inDirectory:nil forLocalization:self.preferredLanguage];
if (!path) path = [self.fallbackBundle pathForResource:filename ofType:type inDirectory:nil forLocalization:self.fallbackLanguage];
if (!path) NSLog(@"Missing file: %@.%@", filename, type);
return path;
}
-(NSString*) localizedStringForKey:(NSString*)key
{
NSString* result = nil;
if (_preferredBundle!=nil) {
result = [_preferredBundle localizedStringForKey:key value:nil table:nil];
}
if (result == nil) {
result = [_fallbackBundle localizedStringForKey:key value:nil table:nil];
}
if (result == nil) {
result = key;
}
return result;
}
@end
这将使用在阿拉伯语文件中查找键字符串,如果缺少键,它将在阿拉伯语文件中查找。如果您希望以另一种方式使用,请从您的按钮处理程序中执行以下操作:
[[Localization sharedInstance] setPreferred:@"ar" fallback:@"en"];
Github 上的示例项目。
如果本地化不起作用
如果本地化不起作用,请使用 plutil 命令行工具来验证文件的格式。它应该输出:Localizable.strings: OK
. 例子:
$ plutil -lint Localizable.strings
Localizable.strings: OK
国际化编程主题 >本地化字符串资源中描述了这种格式。您可以选择添加// single-line
或/* multi-line */
评论。对于非拉丁语言,建议将 Localized.strings 编码为 UTF-16。您可以在 XCode 的检查器窗格中转换编码。
如果它仍然不起作用,请检查您是否在目标的 Copy files 阶段复制 Localizable.strings 文件。请注意,当您在其中添加 Localizable.strings 文件时,有时它们会显示为红色,继续执行此操作直到文件显示为黑色,然后删除红色的文件(我知道,怪不得 Xcode)。