2

我想用英语和阿拉伯语创建一个 iPhone 应用程序。我检查了语言切换器的国际化文档,但是要使其生效,我必须手动更改 iPhone 设置。我不想那样做。所以我的计划是在主屏幕上我将有两个按钮,分别是英语和阿拉伯语。如果用户点击阿拉伯语,我将有阿拉伯语文本,如果用户选择英语,应用程序将是英语。

任何想法/建议如何完成这项工作?

注意:我不想手动更改语言。


编辑 1

根据@Jano,我在下面做了。

创建了新项目。在本地化中添加了阿拉伯语。现在我有两个故事板和两个 InfoPlist.strings 文件。

添加了 Localization.h 和 .m 文件,如答案所示。

目录结构是MyProject-ar.lproj&MyProject-en.lproj

Plist 的内容是"myButton01" = "Back";&"myButton01" = "ظهر";

第一个视图控制器有两个按钮,分别是英语和阿拉伯语。在这些按钮上调用操作。

- (IBAction)pressedEnglish:(id)sender {
    [Localization sharedInstance].fallbackLanguage = @"ar";
    [Localization sharedInstance].preferredLanguage = @"en";
    NSLog(@"pressed english");
}

- (IBAction)pressedArabic:(id)sender {
    [Localization sharedInstance].fallbackLanguage = @"en";
    [Localization sharedInstance].preferredLanguage = @"ar";
    NSLog(@"pressed arabic");
}

在第二个视图控制器中,我添加了一个按钮并将名称命名为myButton. 现在viewDidLoad,我有

[self.myButton setTitle:localize(@"myButton01") forState:UIControlStateNormal];

我希望这应该可以工作,但是当我运行项目时,我看到按钮为myButton01

为什么会发生这种情况?


编辑 2

我有Edit 1问题。我重命名InfoPlist.stringsLocalizable.strings并且它起作用了。但是,但是,无论我按什么按钮,我仍然会收到阿拉伯语文本。

在寻找原因时,我发现这是因为我们在Localization.m

static Localization *shared = nil;
dispatch_once(&pred, ^{
    shared = [[Localization alloc] init];
    shared.fallbackLanguage = @"en";
    shared.preferredLanguage = @"ar";

问题出在最后两行。由于我们已将阿拉伯语设置为首选语言,因此我总是看到阿拉伯语文本。

我需要做哪些更改,以便可以根据按下的按钮进行更改。

4

1 回答 1

4

您想从应用程序 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)。

复制文件

于 2013-01-13T08:41:29.853 回答