I have a UILabel with an attributed string. Here is a printscreen of it:
Now, I have to translate this attributed string to english and italian. I am searching for a way to do this. Can I build this attributed string in code part by part? I have only found a solution where the whole string is set and then the attributes are set by range. But when I translate the string, I don't know the range anymore, because the words are longer or smaller.
Another option is to create localized .rtf files from which to create NSAttributedStrings
:
NSAttributedString *attributedStr = [[NSAttributedString alloc] initWithData:data options:@{NSDocumentTypeDocumentAttribute:NSRTFTextDocumentType} documentAttributes:nil error:nil];
To use dynamic formatting (e.g. set colors, fonts specific to some app settings), I'm using some html-like formatting, with 1-char tags for which I afterwards apply the format from inside the app.
// 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];
}
}
The method could afterwards be used like this:
NSDictionary* highlightAttributes = @{NSForegroundColorAttributeName: [UIColor blueColor],
NSFontAttributeName: [UIFont boldSystemFontOfSize:16]};
NSDictionary *xmlTagsAttributes = @{@"b": highlightAttributes};
[attrStr formatCharXMLTagsUsingAttributes:xmlTagsAttributes];
Where attrStr
may be @"Press <b>Next</b> button to ..."
.