什么是Swift中的NSLocalizedString等价物?

Raf*_*fAl 218 localization nslocalizedstring ios swift

有Swift相当于NSLocalizedString(...)?在Objective-C,我们通常使用:

NSString *string = NSLocalizedString(@"key", @"comment");
Run Code Online (Sandbox Code Playgroud)

我怎样才能在Swift中实现同样的目标?我发现了一个功能:

func NSLocalizedString(
    key: String,
    tableName: String? = default,
    bundle: NSBundle = default,
    value: String = default,
    #comment: String) -> String
Run Code Online (Sandbox Code Playgroud)

但是,它很长并且根本不方便.

dr *_* OX 368

我用下一个解决方案:

1)创建扩展:

extension String {
    var localized: String {
        return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: "")
    }
}
Run Code Online (Sandbox Code Playgroud)

2)在Localizable.strings文件中:

"Hi" = "??????";
Run Code Online (Sandbox Code Playgroud)

3)使用示例:

myLabel.text = "Hi".localized
Run Code Online (Sandbox Code Playgroud)

请享用!;)

--upd: -

对于带注释的案例,您可以使用此解决方案:

1)扩展:

extension String {
    func localized(withComment:String) -> String {
        return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: withComment)
    }
}
Run Code Online (Sandbox Code Playgroud)

2)在.strings文件中:

/* with !!! */
"Hi" = "??????!!!";
Run Code Online (Sandbox Code Playgroud)

3)使用:

myLabel.text = "Hi".localized(withComment: "with !!!")
Run Code Online (Sandbox Code Playgroud)

  • 唯一的问题是,您将无法使用`genstrings`实用程序生成.strings文件. (87认同)
  • 每个人都对这个答案感到非常兴奋,但是大问题(对于任何有多种语言的严肃项目)都是因为"genstrings"只会对传入NSLocalizedString的文字字符串起作用.有了这个聪明的解决方法,你就失去了使用`genstrings`工具更新你的.strings文件的能力,至少对我而言,这意味着我将无法使用这种简化的方法. (44认同)
  • 我发现这个很棒的解决方案在https://github.com/marmelroy/Localize-Swift中实现.genstrings的问题也通过作者包含的自定义python脚本解决.我不是作家. (12认同)
  • 这是一个非常好的主意!通过更改为```func localized(comment:String ="") - > String```我也变得更聪明了所以它变得更小并带有可选的注释:) (9认同)
  • 知道如何与此一起使用`genstrings`吗? (2认同)
  • 我不明白为什么人们会认为这是一个好答案?如果您无法通过Xcode正确导出/导入进行翻译,则完全使用本地化API(甚至带有扩展名)有什么意义呢? (2认同)

Raf*_*fAl 271

NSLocalizedString在斯威夫特的世界同样存在.

func NSLocalizedString(
    key: String,
    tableName: String? = default,
    bundle: NSBundle = default,
    value: String = default,
    #comment: String) -> String
Run Code Online (Sandbox Code Playgroud)

.tableName,bundlevalue参数用default关键字标记,这意味着我们可以在调用函数时省略这些参数.在这种情况下,将使用它们的默认值.

这导致结论是方法调用可以简化为:

NSLocalizedString("key", comment: "comment")
Run Code Online (Sandbox Code Playgroud)

  • 唯一的区别是评论不能为零,而自动完成对于短版本来说远非直观. (43认同)
  • 并非上述在Xcode 6.3中是正确的,Swift 1.2具有来自objective-c的特定变化,评论(如Marcin所述)不能为零,但它可以是""(空). (2认同)
  • nil/empty注释使得稍后在字符串文件中重新定位字符串变得困难; 如果没有别的东西添加类/文件名,它用作评论. (2认同)

Jos*_*osé 25

现有答案的变体:

斯威夫特4:

extension String {

    func localized(withComment comment: String? = nil) -> String {
        return NSLocalizedString(self, comment: comment ?? "")
    }

}
Run Code Online (Sandbox Code Playgroud)

然后,您可以在有或没有评论的情况下使用它:

"Goodbye".localized()
"Hello".localized(withComment: "Simple greeting")
Run Code Online (Sandbox Code Playgroud)

请注意,虽然这genstrings不适用于此解决方案.


小智 11

通过使用这种方式,可以为不同类型创建不同的实现(即Int或自定义类,如CurrencyUnit,...).也可以使用genstrings实用程序扫描此方法调用.只需将例程标志添加到命令中即可

genstrings MyCoolApp/Views/SomeView.swift -s localize -o .
Run Code Online (Sandbox Code Playgroud)

延期:

import UIKit

extension String {
    public static func localize(key: String, comment: String) -> String {
        return NSLocalizedString(key, comment: comment)
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

String.localize("foo.bar", comment: "Foo Bar Comment :)")
Run Code Online (Sandbox Code Playgroud)


JOM*_*JOM 7

为案例创建了一个小帮助方法,其中"comment"始终被忽略.更少的代码更容易阅读:

public func NSLocalizedString(key: String) -> String {
    return NSLocalizedString(key, comment: "")
}
Run Code Online (Sandbox Code Playgroud)

只需将它放在任何地方(类外),Xcode就会找到这种全局方法.

  • 这是不好的做法.除非您自己进行所有翻译,否则建议并提供帮助. (11认同)

Jan*_*Jan 7

Swift 3版本:)...

import Foundation

extension String {
    var localized: String {
        return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: "")
    }
}
Run Code Online (Sandbox Code Playgroud)


Rob*_*rpe 5

也许最好的办法是这样的一个位置.

fileprivate func NSLocalizedString(_ key: String) -> String {
    return NSLocalizedString(key, comment: "")
}
Run Code Online (Sandbox Code Playgroud)

import Foundation
extension String {
    static let Hello = NSLocalizedString("Hello")
    static let ThisApplicationIsCreated = NSLocalizedString("This application is created by the swifting.io team")
    static let OpsNoFeature = NSLocalizedString("Ops! It looks like this feature haven't been implemented yet :(!")
}
Run Code Online (Sandbox Code Playgroud)

你可以像这样使用它

let message: String = .ThisApplicationIsCreated
print(message)
Run Code Online (Sandbox Code Playgroud)

对我来说这是最好的因为

  • 硬编码字符串位于一个特定文件中,因此您想要更改它的那一天非常简单
  • 比每次手动在文件中键入字符串更容易使用
  • genstrings仍然有效
  • 您可以添加更多扩展,例如每个视图控制器一个,以保持整洁

  • 需要注意的是,以所描述的方式定义的字符串是静态字符串.在iOS设置应用中更改语言后,应重新启动该应用.如果没有,请自行重新启动以查看更改.它也可能有内存开销,因为我们一次初始化所有字符串,而不是在需要它们时. (3认同)
  • 我认为最好在这里使用计算属性,比如这个`static var Hello:String = {return NSLocalizedString("Hello")}` (2认同)

小智 5

实际上,您可以使用两个阶段来翻译Swift项目中的文本:

1)第一个阶段是使用旧方法创建所有可翻译字符串:

NSLocalisedString("Text to translate", comment: "Comment to comment")
Run Code Online (Sandbox Code Playgroud)

1.1)然后,您应该使用genstrings生成Localizable.strings:

$ genstrings *swift
Run Code Online (Sandbox Code Playgroud)

2)之后,您应该使用此答案

2.1)根据正则表达式使用XCode的“查找和替换”选项。对于给定的示例(如果您没有评论),正则表达式将为:

NSLocalizedString\((.*)\, comment:\ \"\"\) 
Run Code Online (Sandbox Code Playgroud)

并替换为

$1.localized
Run Code Online (Sandbox Code Playgroud)

或(如果您有意见)

NSLocalizedString\((.*)\, comment:\ (.*)\)
Run Code Online (Sandbox Code Playgroud)

并替换为

$1.localizedWithComment(comment: $2)
Run Code Online (Sandbox Code Playgroud)

您可以根据需要自由使用正则表达式和其他扩展名组合。通常的方法是将整个过程分为两个阶段。希望能有所帮助。