Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 自定义NSLocalizedString?_Iphone_Xcode_Localization_Nslocalizedstring_Localizable.strings - Fatal编程技术网

Iphone 自定义NSLocalizedString?

Iphone 自定义NSLocalizedString?,iphone,xcode,localization,nslocalizedstring,localizable.strings,Iphone,Xcode,Localization,Nslocalizedstring,Localizable.strings,是否可以将NSLocalizedString基础结构(基于localizable.strings)与自定义的“本地化”一起使用 问题是,有些语言对男性和女性有不同的措辞。我想在首次发布时询问用户的性别,然后使用适当的短语。当然,两者都基于同一种语言。我可以用自己的代码来做,但如果可能的话,我宁愿用简单的方法来做。NSLocalizedString只是NSBundle中定义的宏。h 重新定义它或创建一个新的,例如NSGenderAwareLocalizedString,以满足您的需要 使用新的宏,

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


问题是,有些语言对男性和女性有不同的措辞。我想在首次发布时询问用户的性别,然后使用适当的短语。当然,两者都基于同一种语言。我可以用自己的代码来做,但如果可能的话,我宁愿用简单的方法来做。

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


使用新的宏,您可以自由地执行任何您想要的操作:每种语言有两个字符串文件,一个用于男性,一个用于女性。或者,您可以定义一个约定,从阳性本地化字符串的键派生阴性本地化字符串的键。

以下是我的自定义实现,它使用NSLocalizedString,并将注释作为默认值:

(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。用它

确保在应用程序构建阶段添加运行脚本,以便在每次构建时更新Localizable.strings文件,即在Localizable.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";
由于key==view\u settings\u title的值,自定义LocalizedStringHandler将返回注释,即“settings”


瞧,这有一种特殊的机制。 来自苹果参考:

<> >代码>字符串/代码>工具寻找核心基础和基础 默认情况下,字符串宏。它使用这些宏中的信息 在项目的字符串文件中创建字符串项。您可以 还指示genstring在中查找自定义字符串加载函数 除了标准宏之外,您还可以编写和使用这些函数。 您可以使用自定义函数包装内置的字符串加载 并执行一些额外的处理,或者您可以替换 您自己的自定义模型的默认字符串处理行为

如果您想将genstring与您自己的自定义函数一起使用,您的 函数必须使用 基础宏。函数的参数必须匹配 相应宏的参数。当调用
genstrings
,指定
-s
选项,后跟 与NSLocalizedString宏相对应的函数。其他 然后,函数名应该从此基名称生成 您指定了函数名
MyStringFunction
,这是您的另一个函数 名称应为MyStringFunctionFromTable,
MyStringFunctionFromTableInBundle
,以及
MyStringFunctionWithDefaultValue
genstrings
工具查找这些 函数,并使用它们构建相应的字符串文件


要实现您自己的行为,请使用
NSBundle
方法
localizedStringForKey:value:table:

以下是使用注释作为默认值的NSLocalizedString的自定义实现:

-->在这里,我转换成两种语言(英语和意大利语)

-->将此方法放入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;
}
-->通过调用此方法

 self.title = [appDelgate languageSelectedStringForKey:@"Back"];

将其转换为所选语言。

@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;
}

几年来,Xcode已经有了
本地化的\u字符串\u宏\u名称
,因此,如果它们遵循相同的参数结构,您可以将自定义的
NSLocalizedString
替换宏名称放入Xcode,Xcode将正确导出/导入它们,类似于Xcode项目导航器中的

  • 单击项目名称(列表中的第一项)
  • 然后在“打开”选项卡中,单击“项目标签”下的项目
  • 选择生成设置
  • 在右下角的搜索中,输入本地化的\u字符串\u宏\u名称
  • 将自定义函数名添加到显示的设置中(除以现有函数的空格) 示例:NSLocalizedString CFLocalizedString NSBundleLocalizedString

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

    我不确定如何实现第一个想法(我在发布问题之前检查了宏,但找不到为同一语言定义两个本地化文件的方法),但第二个想法很好!!!谢谢。@AmiramStark知道你很久以前就发布了这个,但是因为你不知道如何更好地实施纪尧姆的建议,我添加了一个这样的答案。我认为分解文件有很大的力量