【问题标题】:NSLocalizedString not defaulting to Base languageNSLocalizedString 不默认为基本语言
【发布时间】:2014-03-12 08:52:27
【问题描述】:

我正在测试本地化功能的一个小型 iOS 7 项目遇到以下问题。

  • 我有一个默认项目,有一个 VC,其中我在场景中间有一个按钮
  • 在我的 VC 中,我的按钮有一个名为 myButton 的 IBOutlet
  • 在 VC 的 viewDidLoad 方法中,我正在设置按钮的标题:


    NSString *title = NSLocalizedString(@"MY_BUTTON", @"My comment for my button");
    [self.myButton setTitle:title forState:UIControlStateNormal];

  • 我生成了 Localizable.strings 文件,结束后启用它以支持以下语言的本地化:Base、Dutch
  • 每个文件的内容如下:

/* 我对按钮的评论 */ "MY_BUTTON" = "我的 [VALUE] 按钮";其中 VALUE = Base,荷兰语;所以标签应该是 My Base Button & My Dutch Button

问题: 如果我使用模拟器的语言作为荷兰语启动我的应用程序,则标签是(如预期的那样)“我的荷兰语按钮”。如果我用英文启动它,标签是“My Base Button”(还可以……)

但是,如果我在手机语言设置为法语的情况下启动它,并且我之前将其设置为荷兰语,则按钮的标签不会默认为 Base,而是再次显示“我的荷兰语按钮”

对此有什么想法吗?

谢谢

【问题讨论】:

  • 你是否也为法语设置了 Localizable.strings 文件?
  • 在 Mac 上可以设置语言顺序,也许该顺序在 iOS 上也起作用,并且由于语言设置的顺序是法语、荷兰语、英语?
  • 法语没有 Localizable.strings。我只想支持英语和瑞典语,对于这两种语言以外的设备,我希望应用程序以 Base(即英语)显示
  • 抱歉……我在之前的评论中指的是荷兰语,而不是瑞典语
  • 我想支持两种语言(Base 和 Dutch)。对于其他所有情况(日语、中文、法语、意大利语),我希望我的应用程序默认为 Base(我选择为英语)。现在该应用程序在 Base 和 Dutch 中运行良好,但如果我切换到意大利语/法语/等。它不默认为 Base,但它显示最后使用的语言的值。步骤: 1. 启动应用程序(默认语言:英语)=> 显示我的基本按钮。 2. 将语言更改为荷兰语 => 显示我的荷兰语按钮 3. 将语言更改为法语 => 显示我的荷兰语按钮(我本来希望显示我的基本按钮)

标签: ios objective-c base nslocalizedstring


【解决方案1】:

默认语言的顺序是 OSX 上的用户设置,iOS 上不可编辑 (AFAIK)
但仍然坚持!

应用程序被传递给指定要尝试的语言的数组 AppleLanguages(或其他......)。 NSLocalizedString 宏将尝试按照它们出现的顺序加载数组中的每种语言,直到它找到一个工作的语言,然后使用它

比较:How to force NSLocalizedString to use a specific language

【讨论】:

  • 从 iOS 8 开始,用户首选语言列表是可编辑的。
【解决方案2】:

我创建了以下类,它支持回退到可自定义的语言。就我而言,我使用 Base.lproj 作为默认语言内容的文件。

StringUtilities.h

@interface StringUtils : NSObject

#define GetLocalizedString(key) [StringUtils getLocalizedString:key comment:nil]
//#define GetLocalizedString(key,comment) [StringUtils getLocalizedString:key comment:comment]


+ (NSString*) getLocalizedString:(NSString*)key comment:(NSString*)comment;

@end

StringUtilities.m

#import "StringUtilities.h"

@implementation StringUtils


//Returns a localized string, with fallback to version of Base
+ (NSString*) getLocalizedString:(NSString*)key comment:(NSString*)comment {
    NSString* localizedString = NSLocalizedString(key, nil);

    //use base language if current language setting on device does not find a proper value
    if([localizedString isEqualToString:key]) {

        NSString * path = [[NSBundle mainBundle] pathForResource:@"Base" ofType:@"lproj"];
        NSBundle * bundle = nil;
        if(path == nil){
            bundle = [NSBundle mainBundle];
        }else{
            bundle = [NSBundle bundleWithPath:path];
        }
        localizedString = [bundle localizedStringForKey:key value:comment table:nil];
    }
    return localizedString;
}

@end

如何使用

导入头文件并使用GetLocalizedString宏代替NSLocalizedString宏。

#import "StringUtilities.h"

NSString* str = GetLocalizedString(@"your.text.key");

【讨论】:

    【解决方案3】:

    我在 Swift 中有一个 equivalent

    public func LS(_ key: String) -> String {
        let value = NSLocalizedString(key, comment: "")
        if value != key || NSLocale.preferredLanguages.first == "en" {
            return value
        }
    
        // Fall back to en
        guard
            let path = Bundle.main.path(forResource: "en", ofType: "lproj"),
            let bundle = Bundle(path: path)
            else { return value }
        return NSLocalizedString(key, bundle: bundle, comment: "")
    }
    

    【讨论】:

      【解决方案4】:

      在这里使用 Dirk 的答案是在字符串扩展中实现为计算属性的 Swift 等效项:

      extension String {
      
      var localized: String {
      
          var localizedString = NSLocalizedString(self, comment: "")
      
          // If a localized string was found then return it.
          // This check is based on the fact that if no localized string
          // exists then NSLocalized() returns the key itself.
          if self != localizedString {
              return localizedString
          }
      
          // No localized string exists.  Retrieve the display string
          // from the base strings file.
          var bundleForString: Bundle
          if let path = Bundle.main.path(forResource: "Base", ofType: "lproj"),
              let bundle = Bundle(path: path) {
              bundleForString = bundle
          } else {
              bundleForString = Bundle.main
          }
      
          localizedString = bundleForString.localizedString(forKey: self, value: self, table: nil)
      
          return localizedString
      }
      
      } 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多