在Storyboard中为UITextView进行本地化

4

我有一个应用程序,其中包含不同的按钮、标签和一些文本视图,我在Storyboard中直接输入了文本。我启用了基本本地化并添加了几种语言。

这为基础语言(英语)和其他语言生成了带有项目对象ID列表的Storyboard。我翻译了所有内容,标签和按钮(全部)可以在我设置的语言下正常显示。

然而,无论我设置哪种语言,文本字段仍然显示最初的英文文本...是否需要进行额外的步骤来处理文本视图?


我刚遇到了完全相同的问题。在使用本地化语言的字符串时,模拟器中的一切都正常工作,除了UITextView之外。顺便说一句,当我切换到IB故事板文件时,它像预期的那样工作。Xcode5和Mavericks。 - user1459524
我也遇到了同样的问题。很奇怪!希望有人知道解决方法/修复方法... 我也在使用xxode 5/maverick... - rkh
刚在设备上进行了测试(iPhone5c和iPad),问题还是一样的。所以不仅仅是模拟器的问题。 - user1459524
顺便问一下,你是否在本地化右到左的语言?我也在尝试找出如何根据给定区域设置自动更改文本方向的方法... - rkh
你应该将这个问题发布为一个新的问题。 - user1459524
5个回答

6
因此,我进行了一些研究,似乎为了使其正常工作,UITextView的文本需要以编程方式设置。

来源:Devforums.apple

引用:

据我所知,诸如text view/field的文本属性之类的字符串必须使用NSLocalizedString在代码中设置。如果您有时间观看WWDC 2013视频会话#219“使您的应用程序全球就绪”的前半小时,它将介绍这一点。

因此,似乎解决方法(如果您不想以编程方式设置文本)是在发布应用之前将strings文件转换为storyboard。这似乎可以按预期工作,并显示正确本地化的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, @"");
    }
}

这将从故事板中获取任何内容,并生成百分数编码的字符串,如下所示:

Hello%20World

在你的Localizable.strings文件中,你使用上述内容作为键,这将在运行时为所选语言环境在应用程序中生成本地化文本,如下所示:
"Hello%20World" = "Hallo Welt";

百分号转义功能处理了基础字符串中的所有转义字符。

编辑回复以添加一个解决方法,允许保留.strings文件。 - user1459524

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。我只是把文本视图的恢复标识符设置为其对象标识符,它就起作用了。 - Emma Labbé

1
如果还有人感兴趣,我已经用另一种方式解决了这个问题,这将允许您仍然使用由Xcode为storyboards生成的相同.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.
}

在你的Storyboard中,进入"Identity Inspector"(身份验证器),将 "Object ID" 复制到 "Restoration 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 - Stefan
不幸的是,在iOS 10中,这似乎不再起作用了。相反,调用会返回作为第一个参数提供的ID(例如“abc-xy-pqr.text”)。有什么想法吗? - Stefan

0

我为组件创建了自己的类别。

例如,一个按钮:

#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中使用来自Strings的文本。只需选择LocalizedButton类。 - Robson Ximenes
按钮?谁说过按钮了? - rkh

0

https://stackoverflow.com/users/1950945/stefan的Swift解决方案在我替换“Main”为正确的id(例如“MainStoryboard”)后,在iOS 10.2上适用,该id引用了本地化文件id.storyboard(例如“MainStoryboard.storyboard”)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接