自定义NSLocalizedString?

时间:2011-07-06 08:32:31

标签: iphone xcode localization nslocalizedstring localizable.strings

是否可以将NSLocalizedString基础结构(基于localizable.strings)与自定义“本地化”一起使用?

问题是,有些语言对男性和女性有不同的措辞。我想在首次启动时询问用户的性别,然后使用相应的短语。当然,两者都基于相同的语言。我可以使用我自己的代码来完成它,但如果可能的话,我宁愿这么做。

7 个答案:

答案 0 :(得分:9)

这是我的Custom实现,它使用NSLocalizedString,它使用comment作为默认值:

(NSLocalizedStringWithDefaultValue与genstring无法正常工作,这就是我提出这个解决方案的原因)

1。在预编译的头文件(.pch文件)中,重新定义'NSLocalizedString'宏:

// cutom NSLocalizedString that use macro comment as default value
#import "LocalizationHandlerUtil.h"

#undef NSLocalizedString
#define NSLocalizedString(key,_comment) [[LocalizationHandlerUtil singleton] localizedString:key  comment:_comment]

<强> 2。创建一个类来实现本地化处理程序

#import "LocalizationHandlerUtil.h"

@implementation LocalizationHandlerUtil

static LocalizationHandlerUtil * singleton = nil;

+ (LocalizationHandlerUtil *)singleton
{
    return singleton;
}

__attribute__((constructor))
static void staticInit_singleton()
{
    singleton = [[LocalizationHandlerUtil alloc] init];
}

- (NSString *)localizedString:(NSString *)key comment:(NSString *)comment
{
    // default localized string loading
    NSString * localizedString = [[NSBundle mainBundle] localizedStringForKey:key value:key table:nil];

    // if (value == key) and comment is not nil -> returns comment
    if([localizedString isEqualToString:key] && comment !=nil)
        return comment;

    return localizedString;
}

@end

第3。使用它!

确保在App Build阶段添加Run脚本,以便在每次构建时更新Localizable.strings文件,即新的本地化字符串将添加到Localized.strings文件中:

我的构建阶段脚本是一个shell脚本:

Shell: /bin/sh
Shell script content: find . -name \*.m | xargs genstrings -o MyProjectFolder

因此,当您在代码中添加此新行时:

self.title = NSLocalizedString(@"view_settings_title", @"Settings");

然后执行构建,您的./Localizable.scripts文件将包含以下新行:

/* Settings */
"view_settings_title" = "view_settings_title";

由于'view_settings_title'的key ==值,自定义LocalizedStringHandler将返回注释,即'Settings >>

Voilà: - )

答案 1 :(得分:4)

NSLocalizedString只是NSBundle.h中定义的宏 重新定义或创建一个新的,例如NSGenderAwareLocalizedString以满足您的需求。

使用新宏,您可以随意做任何事情:每种语言两个字符串文件,一个用于男性,一个用于女性。或者,您可以定义一个约定,以便从男性本地化字符串的键中为女性的本地化字符串派生键。

答案 2 :(得分:2)

这有一种特殊的机制。 来自Apple参考:Searching for Custom Functions With genstrings

  

genstrings工具搜索Core Foundation和Foundation   字符串宏默认情况下。它使用这些宏中的信息   在项目的字符串文件中创建字符串条目。您可以   还指示genstrings寻找自定义字符串加载函数   除了标准宏之外,还需要使用这些函数。   您可以使用自定义函数来包装内置字符串加载   例程并执行一些额外的处理,或者你可以替换   使用您自己的自定义模型的默认字符串处理行为。

     

如果你想使用自己的自定义功能的genstrings,你的   函数必须使用的命名和格式约定   基础宏。函数的参数必须与   完全相应宏的参数。当你调用   genstrings,您指定-s选项后跟名称   与NSLocalizedString宏对应的函数。你的另一个   然后应该从此基本名称构建函数名称。例如,如果   你指定了函数名MyStringFunction,你的另一个函数   名称应为MyStringFunctionFromTable,   MyStringFunctionFromTableInBundle,和   MyStringFunctionWithDefaultValuegenstrings工具会查找这些内容   函数并使用它们来构建相应的字符串文件。

要使用NSBundle方法localizedStringForKey:value:table:

实现自己的行为

答案 3 :(得分:2)

这是我的Custom实现,它使用NSLocalizedString,它使用comment作为默认值:

- &GT;在这里,我转换为2种语言(英语和意大利语)

- &GT;将此方法放在appdelegate类

- (NSString*)languageSelectedStringForKey:(NSString*) key {        

    NSString *path = nil;
    NSString *language = [[NSUserDefaults standardUserDefaults] valueForKey:@"AppLanguage"];

    if ([language isEqualToString:@"English"])
        path = [[NSBundle mainBundle] pathForResource:@"en" ofType:@"lproj"];
    else if ([language isEqualToString:@"Italian"])
        path = [[NSBundle mainBundle] pathForResource:@"it" ofType:@"lproj"];

    NSBundle* languageBundle = [NSBundle bundleWithPath:path];
    NSString* str=[languageBundle localizedStringForKey:key value:@"" table:nil];
    return str;
}

- &GT;通过

调用此方法
 self.title = [appDelgate languageSelectedStringForKey:@"Back"];

以所选语言转换回来。

答案 4 :(得分:0)

@Guillaume提供了最佳解决方案,但没有实际显示实现。由于该问题的作者无法弄明白,我决定将其包含在未来的人中。我发现这个帖子很有帮助,现在它不仅仅是有用的。 :)

正如@Guillaume所提到的,最好的解决方案是创建一个自定义宏,并在表上进行查找。 'table'只是包含变体的另一个文件的名称。在这种情况下,我假设您将文件命名为“Female.strings”

这确保了最大的灵活性,并为您提供了一个不需要您为两种情况定义条目的解决方案。这实际上对你的情况非常有用,因为并非所有短语都可能具有女性形式。

因此,以下解决方案不需要重复条目,这非常酷!

首先定义你的宏:

#define SXLocalizedString(key, comment) [Utility SXLocalizedString:key with:comment]

然后定义扩展函数:

+ (NSString*)SXLocalizedString:(NSString*)str with:(NSString*)comment {
    NSString* feminine = NSLocalizedStringFromTable(str, @"Female", comment);
    NSString* value = NSLocalizedString(str, comment);
    if ([self userIsFemale] &&
        feminine) {
        // choose the feminine version of the string
        value = feminine;
    }
    return value;
}

答案 5 :(得分:0)

Xcode已有几年了LOCALIZED_STRING_MACRO_NAMES,因此,如果您的自定义NSLocalizedString替代宏名称遵循相同的参数结构,并且Xcode可以正确导出/导入它们,则类似于{{3} }

答案 6 :(得分:0)

在Xcode项目浏览器中,

  1. 单击项目名称(列表中的第一项),
  2. 然后在打开的选项卡中,单击PROJECT标签下的项目
  3. 选择构建设置
  4. 在右上角的搜索中输入LOCALIZED_STRING_MACRO_NAMES
  5. 将您的自定义函数名称添加到显示的设置(按现有空间除以空格) 示例:NSLocalizedString CFLocalizedString NSBundleLocalizedString enter image description here

此后,Xcode的“导出用于本地化”选项将生成一个XLIFF文件,其中包含您的自定义函数中提到的可翻译字符串。