xcode 自定义 NSLocalizedString?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6593561/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Custom NSLocalizedString?
提问by Amiram Stark
Is it possible to use the NSLocalizedString infrastructure (based on localizable.strings) with a custom-defined "localization"?
是否可以将 NSLocalizedString 基础结构(基于 localizable.strings)与自定义定义的“本地化”一起使用?
The thing is, there are some languages that have different wordings for males and females. I want to ask the user's gender on first launch and then use the appropriate phrases. Of course, both are based on the same language. I can do it with my own code but I'd rather do it the easy way if possible.
问题是,有些语言对男性和女性有不同的措辞。我想在第一次启动时询问用户的性别,然后使用适当的短语。当然,两者都基于相同的语言。我可以用我自己的代码来做,但如果可能的话,我宁愿用简单的方法来做。
回答by Pascal
Here is my Custom implementation that use NSLocalizedString that use comment as default value:
这是我的自定义实现,它使用 NSLocalizedString 并使用注释作为默认值:
(NSLocalizedStringWithDefaultValue does not work properly with genstring, that's why I proposed this solution)
(NSLocalizedStringWithDefaultValue 不能与 genstring 一起正常工作,这就是我提出这个解决方案的原因)
1 . In your pre compiled header (.pch file) , redefine the 'NSLocalizedString' macro:
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. create a class to implement the localization handler
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. Use it!
3. 使用它!
Make sure you add a Run script in your App Build Phases so you Localizable.strings file will be updated at each build, i.e., new localized string will be added in your Localized.strings file:
确保在应用程序构建阶段添加运行脚本,以便在每次构建时更新 Localizable.strings 文件,即,将在 Localized.strings 文件中添加新的本地化字符串:
My build phase Script is a shell script:
我的构建阶段脚本是一个 shell 脚本:
Shell: /bin/sh
Shell script content: find . -name \*.m | xargs genstrings -o MyProjectFolder
So when you add this new line in your code:
因此,当您在代码中添加此新行时:
self.title = NSLocalizedString(@"view_settings_title", @"Settings");
Then perform a build, your ./Localizable.scripts file will contain this new line:
然后执行构建,您的 ./Localizable.scripts 文件将包含以下新行:
/* Settings */
"view_settings_title" = "view_settings_title";
And since key == value for 'view_settings_title', the custom LocalizedStringHandler will returns the comment, i.e. 'Settings"
并且由于“view_settings_title”的键 == 值,自定义 LocalizedStringHandler 将返回注释,即“设置”
Voilà :-)
瞧:-)
回答by Guillaume
NSLocalizedString is just a macro defined in NSBundle.h
Redefine it or create a new one, for example NSGenderAwareLocalizedString to fit your needs.
NSLocalizedString 只是在 NSBundle.h 中
定义的一个宏,重新定义它或创建一个新的宏,例如 NSGenderAwareLocalizedString 以满足您的需求。
With the new macro, you are free to do whatever you want: two strings files per language, one for male and one for female. Or you can define a convention to derivate the key for a localized string for a female from the key of the male localized string.
使用新宏,您可以随意执行任何操作:每种语言有两个字符串文件,一个用于男性,一个用于女性。或者,您可以定义一个约定,从男性本地化字符串的键中导出女性本地化字符串的键。
回答by DanSkeel
There is a special mechanism for this. From Apple reference: Searching for Custom Functions With genstrings
这有一个特殊的机制。来自 Apple 参考:Searching for Custom Functions With genstrings
The
genstrings
tool searches for the Core Foundation and Foundation string macros by default. It uses the information in these macros to create the string entries in your project's strings files. You can also direct genstrings to look for custom string-loading functions in your code and use those functions in addition to the standard macros. You might use custom functions to wrap the built-in string-loading routines and perform some extra processing or you might replace the default string handling behavior with your own custom model.If you want to use genstrings with your own custom functions, your functions must use the naming and formatting conventions used by the Foundation macros. The parameters for your functions must match the parameters for the corresponding macros exactly. When you invoke
genstrings
, you specify the-s
option followed by the name of the function that corresponds to the NSLocalizedString macro. Your other function names should then build from this base name. For example, if you specified the function nameMyStringFunction
, your other function names should beMyStringFunctionFromTable
,MyStringFunctionFromTableInBundle
, andMyStringFunctionWithDefaultValue
. Thegenstrings
tool looks for these functions and uses them to build the corresponding strings files.
该
genstrings
工具默认搜索 Core Foundation 和 Foundation 字符串宏。它使用这些宏中的信息在项目的字符串文件中创建字符串条目。您还可以指示 genstrings 在您的代码中查找自定义字符串加载函数,并在标准宏之外使用这些函数。您可以使用自定义函数来包装内置的字符串加载例程并执行一些额外的处理,或者您可以用您自己的自定义模型替换默认的字符串处理行为。如果您想将 genstring 与您自己的自定义函数一起使用,您的函数必须使用 Foundation 宏使用的命名和格式约定。函数的参数必须与相应宏的参数完全匹配。调用时
genstrings
,指定-s
选项后跟对应于 NSLocalizedString 宏的函数名称。然后您的其他函数名称应该从这个基本名称构建。例如,如果你指定的函数名称MyStringFunction
,你的其他函数名应该是MyStringFunctionFromTable
,MyStringFunctionFromTableInBundle
和MyStringFunctionWithDefaultValue
。该genstrings
工具会查找这些函数并使用它们来构建相应的字符串文件。
To implement your own behaviour use NSBundle
method localizedStringForKey:value:table:
实现你自己的行为使用NSBundle
方法localizedStringForKey:value:table:
回答by Pooja Jalan
Here is my Custom implementation that use NSLocalizedString that use comment as default value:
这是我的自定义实现,它使用 NSLocalizedString 并使用注释作为默认值:
--> Here I convert in 2 Language (English and Italian)
--> 在这里我转换成 2 种语言(英语和意大利语)
--> Put this method in appdelegate class
--> 将此方法放在 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;
}
--> call this method by
--> 调用这个方法
self.title = [appDelgate languageSelectedStringForKey:@"Back"];
that convert Back in selected language.
转换回选定的语言。
回答by MobileVet
@Guillaume provides the best solution, without actually showing the implementation. Since the author of the question wasn't able to figure it out, I decided to include it for future people. I found the thread helpful, now it is more than helpful. :)
@Guillaume 提供了最佳解决方案,但并未实际展示实现。由于问题的作者无法弄清楚,我决定将其包含在未来的人中。我发现该线程很有帮助,现在它不仅有帮助。:)
As mentioned by @Guillaume, the best solution is to create a custom macro with a lookup on the table . The 'table' is just the name of the other file that contains the variants. In this case, I am assuming you will name your file 'Female.strings'
正如@Guillaume 所提到的,最好的解决方案是创建一个在 table 上查找的自定义宏。“表”只是包含变体的另一个文件的名称。在这种情况下,我假设您将文件命名为“Female.strings”
This ensures the most flexibility and gives you a solution that doesn't require you to define entries for BOTH cases. This is actually really useful for your case as not all phrases may have feminine forms.
这确保了最大的灵活性,并为您提供了一个不需要您为两种情况定义条目的解决方案。这实际上对您的情况非常有用,因为并非所有短语都可能具有女性形式。
As a result, the following solution doesn't require duplicate entries, which is pretty cool!
结果,下面的解决方案不需要重复条目,这很酷!
First define your macro:
首先定义你的宏:
#define SXLocalizedString(key, comment) [Utility SXLocalizedString:key with:comment]
Then define the expanded function as such:
然后这样定义扩展函数:
+ (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;
}
回答by ReDetection
For couple of years Xcode has LOCALIZED_STRING_MACRO_NAMES
, so you can put your custom NSLocalizedString
alternative macro names if they follow same parameters structure and Xcode will correctly export/import them, similar to genstrings answer
几年来 Xcode 有LOCALIZED_STRING_MACRO_NAMES
,因此您可以放置自定义的NSLocalizedString
替代宏名称,如果它们遵循相同的参数结构并且 Xcode 将正确导出/导入它们,类似于genstrings 答案