故事板中 UITextView 的本地化
Posted
技术标签:
【中文标题】故事板中 UITextView 的本地化【英文标题】:Localization for UITextView in storyboard 【发布时间】:2013-11-18 00:25:01 【问题描述】:所以我有一个应用程序,在情节提要中有不同的按钮、标签和一些文本视图,我直接在情节提要中输入了文本。我启用了基本本地化并添加了几种语言。
这为基础(英语)和其他语言生成了故事板,其中包含项目 objectID 列表。 我翻译了所有内容,标签和按钮(全部)以我设置设备的语言工作和显示。
无论我设置哪种语言,文本字段都会一直显示初始英文文本... 文本视图是否涉及任何额外步骤?
【问题讨论】:
我刚刚遇到了完全相同的问题。使用本地化语言的字符串时,除了 UITextViews 在模拟器中一切正常。当我切换到 IB 故事板文件时,它确实按预期工作,顺便说一句。 Xcode5 和小牛队。 这里也一样。奇怪的问题!希望有人知道解决方法/修复方法...我也是 xxode 5/maverick... 刚刚在设备(iPhone5c 和 iPad)上测试过,同样的问题。所以它不仅仅是模拟器。 顺便说一句,您在哪里本地化了从右到左的语言?我还试图弄清楚如何自动更改给定语言环境的文本方向... 您应该将此作为新问题发布。 【参考方案1】:所以,我做了一些研究,似乎为了使其正常工作,需要以编程方式设置 UITextView 的文本。
来源:Devforums.apple
引用:
据我了解,必须使用 NSLocalizedString 在代码中设置诸如文本视图/字段的文本属性之类的字符串。如果您有时间观看,WWDC 2013 视频会议 #219 让您的 App World Ready 的前 1/2 小时涵盖了这一点
因此,似乎解决方法(如果您不想以编程方式设置文本)是在发布应用程序之前将字符串文件转换为情节提要。这似乎确实按预期工作,并显示 UITextView 正确本地化。
编辑:找到另一个允许保留 .strings 文件的解决方法。
在- (void)viewDidLoad
:
for(UIView* v in self.view.subviews)
if([v isKindOfClass:[UITextView class]])
UITextView* txv = (UITextView*)v;
NSString *loctxt = [txv.text stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
txv.text = NSLocalizedString(loctxt, @"");
这会从情节提要中的任何内容生成 Percent Escapes 编码字符串,如下所示:
Hello%20World
在您的Localizable.strings
文件中,您使用上述作为键,这将在运行时为所选语言环境在应用程序中生成本地化文本,如下所示:
"Hello%20World" = "Hallo Welt";
百分比转义处理基本字符串中的所有转义字符。
【讨论】:
编辑回复以添加允许保留 .strings 文件的解决方法【参考方案2】:由于我对 Dmitry 答案的评论无法很好地格式化,我在此重复此作为答案。他的解决方案的 Swift 版本如下所示:
override func viewDidLoad()
super.viewDidLoad()
for view in self.view.subviews
if let tv = view as? UITextView, ident = view.restorationIdentifier
tv.text = NSLocalizedString("\(ident).text", tableName: "Main", comment: "")
// Do any additional setup after loading the view.
(请注意,在 Swift 中,NSLocalizedString
替换了多个 Objective-C 宏,其中之一是 NSLocalizedStringFromTable
)
P.S.:不幸的是,在 ios 10 中,这似乎不再适用。相反,该调用返回作为第一个参数提供的 id(例如“abc-xy-pqr.text
”)。有什么想法吗?
【讨论】:
restorationIdentifier
为我返回了nil
。我只是将 Text View 的 Restoration Identifier 设置为它的 Object ID 并且它起作用了。【参考方案3】:
如果有人仍然感兴趣,我已经用不同的方式解决了这个问题,这将允许您仍然使用由 Xcode 为情节提要生成的 SAME .Strings 文件。
这个解决方案有两个部分:
在您的视图的 .m 文件中添加以下代码:
- (void)viewDidLoad
[super viewDidLoad];
for(UIView* view in self.view.subviews)
if([view isKindOfClass:[UITextView class]] && view.restorationIdentifier)
UITextView* textView = (UITextView*)view;
NSString *textViewName = [NSString stringWithFormat:@"%@.text",textView.restorationIdentifier];
textView.text = NSLocalizedStringFromTable(textViewName, @"Main", nil);
//change this to be the same as the name of your storyboard ^^^
// Do any additional setup after loading the view.
然后在身份检查器的情节提要中将“对象 ID”复制到“恢复 ID”字段。
这会将新的本地化文本应用于屏幕加载时的所有 UITextView,并允许您使用已生成的字符串文件。
【讨论】:
这是一个非常方便的解决方案。在 Swift 中,for
循环看起来像 for view in self.view.subviews if let tv = view as? UITextView, ident = view.restorationIdentifier let textViewName = String(format: "%@.text", ident); tv.text = NSLocalizedString(textViewName, tableName: "Main", comment: "")
(请注意,在 Swift 中,NSLocalizedString
替换了几个 Obj-C 宏,其中一个是 NSLocalizedStringFromTable
)
不幸的是,在 iOS 10 中,这似乎不再起作用。相反,该调用返回作为第一个参数提供的 id(例如“abc-xy-pqr.text”)。有什么想法吗?【参考方案4】:
我为组件创建了自己的类别。
例如一个按钮:
#import <UIKit/UIKit.h>
@interface LocalizedButton : UIButton
@end
#import "LocalizedButton.h"
@implementation LocalizedButton
- (id)initWithCoder:(NSCoder *)aDecoder
NSLog(@"Loading LocalizedButton: initWithCoder");
if ((self = [super initWithCoder:aDecoder]))
[self localizeButton];
return self;
- (id)initWithFrame:(CGRect)frame
NSLog(@"Loading LocalizedButton: initWithFrame");
self = [super initWithFrame:frame];
if (self)
[self localizeButton];
return self;
-(void) localizeButton
self.titleLabel.adjustsFontSizeToFitWidth = YES;
NSString* text = NSLocalizedString(self.titleLabel.text, nil);
[self setTitle:text forState:UIControlStateNormal];
[self setTitle:text forState:UIControlStateHighlighted];
[self setTitle:text forState:UIControlStateDisabled];
[self setTitle:text forState:UIControlStateSelected];
@end
您可以在以下位置查看完整代码:https://github.com/exmo/equizmo-ios/blob/master/Quiz/LocalizedButton.m
【讨论】:
因此,您可以在 xcode 上使用字符串中的文本。只需选择类 LocalizedButton。 按钮?谁说过按钮?【参考方案5】:https://***.com/users/1950945/stefan 的 Swift 解决方案适用于我在 iOS 10.2 上,当我将“Main”替换为引用本地化文件 id.storyboard(例如“MainStoryboard.storyboard”)的正确 ID(例如“MainStoryboard”)时
【讨论】:
以上是关于故事板中 UITextView 的本地化的主要内容,如果未能解决你的问题,请参考以下文章
iOS Swift 2.0 UITextView 根据文本冻结应用程序
UIScrollView 中的 Storyboard UITextview 和按钮
UITextView insertText 调用 shouldChangeTextInRange: replacementText: