【问题标题】:Custom NSLocalizedString?自定义 NSLocalizedString?
【发布时间】:2011-09-29 10:19:29
【问题描述】:

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

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

【问题讨论】:

    标签: iphone xcode localization nslocalizedstring localizable.strings


    【解决方案1】:

    这是我使用 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 文件将在每次构建时更新,即,新的本地化字符串将添加到您的 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 == value,自定义LocalizedStringHandler将返回注释,即'Settings'

    瞧 :-)

    【讨论】:

    • 我在其他地方看到了完全相同的答案。有人复制了您的答案,或者您可以提供指向该答案的链接;)
    • 不记得...会检查。谢谢
    【解决方案2】:

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

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

    【讨论】:

    • 我不确定如何实现第一个想法(我在发布问题之前检查了宏,但找不到为同一语言定义两个本地化文件的方法),但第二个想法是很棒的!!!谢谢。
    • @AmiramStark 意识到你很久以前就发布了这个,但由于你不确定如何更好地实施纪尧姆的建议,所以我添加了一个答案。我认为拆分文件并且不需要两者中的匹配键有很大的力量。
    【解决方案3】:

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

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

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

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

    【讨论】:

      【解决方案4】:

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

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

      --> 把这个方法放到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"];
      

      以所选语言转换回来。

      【讨论】:

        【解决方案5】:

        在 Xcode 项目导航器中,

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

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

        【讨论】:

          【解决方案6】:

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

          【讨论】:

            【解决方案7】:

            几年来 Xcode 有 LOCALIZED_STRING_MACRO_NAMES,因此如果它们遵循相同的参数结构,您可以使用自定义的 NSLocalizedString 替代宏名称,Xcode 将正确导出/导入它们,类似于 genstrings answer

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2011-12-14
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多