UIBarButtonItem具有Cancel、Done和其他一些标识符。它们以文本形式显示给用户。如果用户更改语言,例如取消按钮将自动翻译。作为开发人员,您不需要为这些按钮提供本地化字符串。这意味着Cancel、Done和其他字符串已经本地化,并随操作系统一起提供。
是否有一种方法可以通过编程方式获取这些字符串?
我不想向本地化文件添加额外的字符串。如果可以访问,则非常好。
UIBarButtonItem具有Cancel、Done和其他一些标识符。它们以文本形式显示给用户。如果用户更改语言,例如取消按钮将自动翻译。作为开发人员,您不需要为这些按钮提供本地化字符串。这意味着Cancel、Done和其他字符串已经本地化,并随操作系统一起提供。
是否有一种方法可以通过编程方式获取这些字符串?
我不想向本地化文件添加额外的字符串。如果可以访问,则非常好。
这是我创建的一个小宏,用于获取系统UIKit字符串:
#define UIKitLocalizedString(key) [[NSBundle bundleWithIdentifier:@"com.apple.UIKit"] localizedStringForKey:key value:@"" table:nil]
像这样使用:
UIKitLocalizedString(@"Search");
UIKitLocalizedString(@"Done");
UIKitLocalizedString(@"Cancel");
...
一种(尽管有争议的)轻松完成此事的方法是直接使用苹果的框架束本地化:
要查看它们提供了什么,请通过Finder打开以下目录:
/Applications/Xcode/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator6.1.sdk/System/Library/Frameworks
在您的情况下,您随后将打开./UIKit.framework/English.lproj/Localizable.strings
(在TextMate中)。在这里,您可以看到苹果用于"Print"、"OK"、"On"、"Off"等内容的各种翻译。真正的奇迹在于,您可以免费复制约35种不同的语言翻译到自己的Localizable.strings文件中。
如果您非常大胆且不介意将应用程序的未来稳定性置于问题中,则可以跳过整个“将其复制到自己的Localizable.strings”过程并直接从源代码执行:
NSBundle *uiKitBundle = [NSBundle bundleWithIdentifier:@"com.apple.UIKit"];
NSString *onText = uiKitBundle ? [uiKitBundle localizedStringForKey:@"Yes" value:nil table:nil] : @"YES";
NSString *offText = uiKitBundle ? [uiKitBundle localizedStringForKey:@"No" value:nil table:nil] : @"NO";
注意:我绝不建议您在打算提交到App Store的应用程序中以编程方式访问这些本地化资源。我只是演示了一个特定的实现,以解决您最初的问题。
在这个问题(由Stephan Heilner提出)和答案(由bdunagan提供)的鼓舞下,寻找iPhone/iOS:如何获得应用程序中所有本地化字符串的语言列表?。
Objective-C
NSString * LocalizedString(NSString *key) {
return [[NSBundle mainBundle] localizedStringForKey:key];
}
@interface NSBundle(Localization)
- (NSString *)localizedStringForKey:(NSString *)key;
- (NSDictionary<NSString *, NSString *> *)localizationTable;
@end
@implementation NSBundle(Localization)
- (NSDictionary<NSString *, NSString *> *)localizationTable {
NSString *path = [self pathForResource:@"Localizable" ofType:@"strings"];
NSData *data = [NSData dataWithContentsOfFile:path];
NSError *error = nil;
id obj = [NSPropertyListSerialization propertyListWithData:data options:NSPropertyListImmutable format:NULL error:&error];
if (error && obj == nil) {
@throw error;
return nil;
}
if ([obj isKindOfClass:NSDictionary.class]) {
return obj;
}
@throw NSInternalInconsistencyException;
return nil;
}
- (NSString *)localizedStringForKey:(NSString *)key {
return [self localizedStringForKey:key value:nil table:nil];
}
@end
Swift 5
public extension String {
func localized(_ bundle: Bundle = .main) -> String {
bundle.localize(self)
}
var localized: String {
return localized()
}
}
extension Bundle {
static var UIKit: Bundle {
Self(for: UIApplication.self)
}
func localize(_ key: String, table: String? = nil) -> String {
self.localizedString(forKey: key, value: nil, table: nil)
}
var localizableStrings: [String: String]? {
guard let fileURL = url(forResource: "Localizable", withExtension: "strings") else {
return nil
}
do {
let data = try Data(contentsOf: fileURL)
let plist = try PropertyListSerialization.propertyList(from: data, format: .none)
return plist as? [String: String]
} catch {
print(error)
}
return nil
}
}
使用方法:
"Photo Library".localized(.UIKit)
Bundle.UIKit.localizableStrings?.keys//.map { $0 }
虽然可能不是你正在寻找的完全内容,但在Mac应用商店中有一个名为“System Strings”的商业应用程序声称提供了超过53000个标准本地化字符串的集合。该应用程序于2012年11月2日发布。我与此应用程序或作者无任何关联。URL是https://itunes.apple.com/us/app/systemstrings/id570467776。
Localizable.strings
资源文件中,或者按照其他评论中所述从 UIBarButtonItem 中提取标题(我个人会选择资源文件)。iOS 16 中的工作版本。之前的版本似乎不再起作用了。
+(NSString*) uiKitLocalizedStringForKey:(NSString*)key {
NSBundle* uikitBundle = [NSBundle bundleForClass:[UIButton class]];
if (!uikitBundle) {
// Never seen this happen, but might as well guard for it
return key;
}
return [uikitBundle localizedStringForKey:key value:key table:nil];
}
为什么不在你的Storyboard中使用基本本地化呢?它会自动为你进行本地化。
NSLocalizedString(@"Cancel", @"Cancel")