我有一个带有属性字符串的UILabel。这是它的打印屏幕:
现在,我必须将此属性字符串翻译为英语和意大利语。 我正在寻找一种方法来做到这一点。我可以逐个代码地在代码中构建这个属性字符串吗?我只找到了一个解决方案,其中设置了整个字符串,然后通过范围设置属性。但是当我翻译字符串时,我不再知道范围,因为这些字词更长或更小。
答案 0 :(得分:6)
另一种选择是创建本地化的.rtf文件,从中创建NSAttributedStrings
:
NSAttributedString *attributedStr = [[NSAttributedString alloc] initWithData:data options:@{NSDocumentTypeDocumentAttribute:NSRTFTextDocumentType} documentAttributes:nil error:nil];
要使用动态格式设置(例如设置颜色,特定于某些应用设置的字体),我使用一些类似html的格式,使用1-char标签,然后我会在应用内部应用格式。
// NSMutableAttributedString category method
/**
* Updates the attributes of xml elements (where the xml tags are formed of 1 single char) with the passed attributes from param `tagsAttributes`
* Current version doesn't support recursive tags (tags in tags)
* All tags of form '<char>' or '</char>' will be used as formatting (the resulting string should not be expected to have any tags of this form)
* @param tagsAttributes - list of attribute dictionaries, where the key is the tag name */
-(void)formatCharXMLTagsUsingAttributes:(NSDictionary *)tagsAttributes {
int strippedLength = 0;
NSString *str = [[self string] copy];
NSScanner *scanner = [NSScanner scannerWithString:str];
while (![scanner isAtEnd]) {
NSString *tag = nil;
do {
[scanner scanUpToString:@"<" intoString:nil];
[scanner scanString:@"<" intoString:nil];
if (scanner.scanLocation + 2 < [str length] && [str characterAtIndex:scanner.scanLocation + 1] == '>') {
[scanner scanUpToString:@">" intoString:&tag];
[scanner scanString:@">" intoString:nil];
}
} while (!tag && ![scanner isAtEnd]);
if ([scanner isAtEnd]) {
break;
}
NSString *endTag = [NSString stringWithFormat:@"</%@>", tag];
NSString *tmpString;
[scanner scanUpToString:endTag intoString:&tmpString];
[scanner scanString:endTag intoString:nil];
NSRange range;
strippedLength += 7; // start tag + end tag length
range.location = scanner.scanLocation - [tmpString length] - strippedLength;
range.length = [tmpString length] + 7;
[self replaceCharactersInRange:range withString:tmpString];
range.length -= 7;
[self addAttributes:tagsAttributes[tag] range:range];
}
}
之后可以像这样使用该方法:
NSDictionary* highlightAttributes = @{NSForegroundColorAttributeName: [UIColor blueColor],
NSFontAttributeName: [UIFont boldSystemFontOfSize:16]};
NSDictionary *xmlTagsAttributes = @{@"b": highlightAttributes};
[attrStr formatCharXMLTagsUsingAttributes:xmlTagsAttributes];
attrStr
可能是@"Press <b>Next</b> button to ..."
。
答案 1 :(得分:2)
像这种方法可以起作用。它需要NSAttributedString,根据属性提取部分,翻译每个部分,应用相同的属性,最后返回完整的翻译属性字符串。
-(NSAttributedString*)translateAttribString:(NSAttributedString*)attribString toLanguage:(NSString*)language
{
NSMutableAttributedString *returnString = [[NSMutableAttributedString alloc]init];
NSRange totalRange = NSMakeRange (0, attribString.length);
[attribString enumerateAttributesInRange: totalRange options: 0 usingBlock: ^(NSDictionary *attributes, NSRange range, BOOL *stop)
{
NSLog (@"range: %@ attributes: %@", NSStringFromRange(range), attributes);
NSString *string = [[attribString string] substringWithRange:range];
NSLog(@"string at range %@", string);
//Translate 'string' based on 'language' here.
NSString *trans; //This will hold the translated string.
NSAttributedString *translatedString = [[NSAttributedString alloc]initWithString:trans attributes:attributes];
[returnString appendAttributedString:translatedString];
}];
return returnString;
}
答案 2 :(得分:1)
您可以利用可以从HTML数据构造属性字符串的事实。因此,将带有嵌入式HTML属性的字符串写在Localized.string中:
MY_STRING = "some <b>bold</b> string";
然后您可以像这样检索它
let htmlTitle = NSLocalizedString("MY_STRING", comment: "")
let data = htmlTitle.data(using: .utf8)!
let attributedTitle = NSAttributedString(html: data, options:[:], documentAttributes: nil)
myLabel.attributedText = attributedTitle!
请注意,您将需要对属性做更多的工作来设置正确的字体,因为它将使用默认字体显示html(Helvetica吗?)。
答案 3 :(得分:0)
我会通过翻译字符串的各个部分来解决这个问题。这将适用于这种情况,因为您的属性字符串确实是四个字符串的连接版本。
但请确保保存使用数字的格式。在某些语言中,文本可能是“3 Erweiterung”。您可以使用NSLocalizedStringWithDefaultValue
执行此操作。
NSString *stepFormat = NSLocalizedStringWithDefaultValue(@"AttributedStringStepFormat", @"main", [NSBundle mainBundle], @"Step %ld", @"'Step 4' in 'Step 4 - Erweiterung 3 - erhalten\ndauerhaft'");
NSString *step = [NSString stringWithFormat:stepFormat, (long)4];
NSString *erweiterungFormat = NSLocalizedStringWithDefaultValue(@"AttributedStringErweiterungFormat", @"main", [NSBundle mainBundle], @"Erweiterung %ld", @"'Erweiterung 3' in 'Step 4 - Erweiterung 3 - erhalten\ndauerhaft'");
NSString *erweiterung = [NSString stringWithFormat:erweiterungFormat, (long)3];
NSString *erhalten = NSLocalizedStringWithDefaultValue(@"AttributedStringErhalten", @"main", [NSBundle mainBundle], @"erhalten", @"'erhalten' in 'Step 4 - Erweiterung 3 - erhalten\ndauerhaft'");
NSString *dauerhaft = NSLocalizedStringWithDefaultValue(@"AttributedStringDauerhaft", @"main", [NSBundle mainBundle], @"dauerhaft", @"'dauerhaft' in 'Step 4 - Erweiterung 3 - erhalten\ndauerhaft'");
NSString *result = [NSString stringWithFormat:@"%@ - %@ - %@\n%@", step, erweiterung, erhalten, dauerhaft];
NSRange stepRange = [result rangeOfString:step];
NSRange erweiterungRange = [result rangeOfString:erweiterung];
NSRange erhaltenRange = [result rangeOfString:erhalten];
NSRange dauerhaftRange = [result rangeOfString:dauerhaft];
// Create attributed string
通过这种方式,您可以获得可用于翻译的精美字符串文件:
/* 'dauerhaft' in 'Step 4 - Erweiterung 3 - erhalten\ndauerhaft' */
"AttributedStringDauerhaft" = "dauerhaft";
/* 'erhalten' in 'Step 4 - Erweiterung 3 - erhalten\ndauerhaft' */
"AttributedStringErhalten" = "erhalten";
/* 'Erweiterung 3' in 'Step 4 - Erweiterung 3 - erhalten\ndauerhaft' */
"AttributedStringErweiterungFormat" = "Erweiterung %ld";
/* 'Step 4' in 'Step 4 - Erweiterung 3 - erhalten\ndauerhaft' */
"AttributedStringStepFormat" = "Step %ld";
答案 4 :(得分:0)
我通常会单独翻译突出显示的部分,并在原始文本中添加独特的占位符,以便于查找和替换。
示例:&#34;此字为粗体&#34;
在localized.strings中,它将是
&#34; BaseText&#34; =&#34;这个-Word-是粗体&#34;;
&#34; HighlightedText&#34; =&#34;字&#34 ;;
现在我们可以使用&#34; BaseText&#34;键和:
1.找到&#34; -Word - &#34;的范围。子
2.将其替换为带有&#34; HighlightedText&#34;的本地化字符串。键。
3.使用原始占位符的范围,原始占位符的长度和翻译长度,您可以轻松计算新范围并应用特定属性。
这种方法比连接更灵活,不依赖于翻译中的单词顺序。
这是它的延伸:
extension NSMutableAttributedString {
func replacePlaceholder(_ placeholder: String, with translation: String, attributes: [String: Any]) {
// find the placeholder
var range = (string as NSString).range(of: placeholder)
// nothing to replace
if range.location == NSNotFound {
return
}
// replace it with the translation
mutableString.replaceCharacters(in: range, with: translation)
// adjust range according to changes
range.length = range.length + translation.length - placeholder.length
// apply attributes
self.setAttributes(attributes, range: range)
}
}
如果需要,您可以一个接一个地替换多个占位符。