2014-04-04 11 views
11

Ich habe ein UILabel mit einer attributierten Zeichenfolge. Hier ist ein print davon:Übersetzen attributierte Zeichenfolge

enter image description here

Jetzt habe ich diese Zeichenfolge auf Englisch und Italienisch zugeschrieben übersetzen. Ich suche nach einer Möglichkeit, dies zu tun. Kann ich diese attributierte Zeichenfolge Teil für Code erstellen? Ich habe nur eine Lösung gefunden, bei der die ganze Zeichenfolge gesetzt ist und dann werden die Attribute durch die Entfernung festgelegt. Aber wenn ich die Zeichenfolge übersetze, kenne ich den Bereich nicht mehr, weil die Wörter länger oder kleiner sind.

+0

Verwenden Sie die NSAttributedString-Methode 'enumerateAttributesInRange: options: usingBlock:'. Dies gibt jedes Attribut mit seinem Bereich zurück. Sie können die Zeichenfolge aus diesem Bereich Stück für Stück extrahieren und übersetzen. – ZeMoon

Antwort

6

Eine weitere Option ist lokalisierte .rtf-Dateien zu erstellen, aus denen NSAttributedStrings zu erstellen:

NSAttributedString *attributedStr = [[NSAttributedString alloc] initWithData:data options:@{NSDocumentTypeDocumentAttribute:NSRTFTextDocumentType} documentAttributes:nil error:nil]; 

dynamische Formatierung zu verwenden (zB Set Farben, Schriftarten auf einige App-spezifische Einstellungen), ich bin mit etwas html-ähnliche Formatierung, mit 1-Zeichen-Tags, für die ich später das Format aus der App heraus anwende.

NSDictionary* highlightAttributes = @{NSForegroundColorAttributeName: [UIColor blueColor], 
           NSFontAttributeName: [UIFont boldSystemFontOfSize:16]}; 
NSDictionary *xmlTagsAttributes = @{@"b": highlightAttributes}; 
[attrStr formatCharXMLTagsUsingAttributes:xmlTagsAttributes]; 

Wo attrStr können @"Press <b>Next</b> button to ...":

// 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]; 
    } 
} 

Das Verfahren könnte danach wie folgt verwendet werden.

0

Ich würde dies lösen, indem Sie die einzelnen Teile der Zeichenfolge übersetzen. Dies wird in diesem Fall funktionieren, da Ihr attributierter String tatsächlich eine verkettete Version von vier Strings ist.

Aber stellen Sie sicher, dass Sie das Format speichern, in dem Sie Zahlen verwenden. In manchen Sprachen könnte der Text "3   Erweiterung" lauten. Sie können dies tun, indem Sie NSLocalizedStringWithDefaultValue verwenden.

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 

So kann man eine schöne Saiten bekommen Datei, die Sie übersetzen können:

/* '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"; 
+0

Ich glaube nicht, dass das für Arabisch funktioniert. – OlivaresF

+1

Was funktioniert für Arabisch bei der Lokalisierung? :) – Lope

+1

@Lope Alles funktioniert mit Lokalisierung, wenn Sie wissen, wie es geht. :) Für einen Starter: https://developer.apple.com/library/content/documentation/MacOSX/Conceptual/BPInternational/SupportRight-To-LeftLanguages/SupportingRight-To-LeftLanguages.html – Manuel

2

So etwas wie diese Methode funktionieren könnte. Es nimmt einen NSAttributedString, extrahiert Teile anhand ihrer Attribute, übersetzt jedes Teil, wendet dieselben Attribute an und gibt schließlich die vollständig übersetzte attributierte Zeichenfolge zurück.

-(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; 
} 
0

Normalerweise übersetze ich hervorgehobene Teile separat und füge dem Originaltext eindeutige Platzhalter hinzu, die einfach zu finden und zu ersetzen sind.

Beispiel für: "Dieses Wort fett ist"

In localized.strings wird es
"basetext" = "Dieser -Word- fett ist";
"HighlightedText" = "Wort";

Jetzt können wir die ursprüngliche Zeichenfolge mit „basetext“ Schlüssel nehmen und:
1. Finden Sie den Bereich der „-Word-“ Teilzeichenfolge
2. Ersetzen Sie es mit lokalisierten String mit „HighlightedText“ -Taste.
3. Mit dem ursprünglichen Platzhalterbereich, der ursprünglichen Platzhalterlänge und der Übersetzungslänge können Sie leicht einen neuen Bereich berechnen und ihm bestimmte Attribute zuweisen.

Dieser Ansatz ist flexibler als Verkettung und hängt nicht von der Reihenfolge der Wörter in einer Übersetzung ab.

Dies ist eine Erweiterung für sie:

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) 
    } 
} 

Sie mehrere Platzhalter nacheinander ersetzen kann, wenn nötig.