2017-02-04 2 views
2

Wenn ich Attribute attributierte Zeichenfolge, die Emojis enthält, hinzufügen möchte, sind manchmal einige der Emojis gebrochen. Für normalen Text funktioniert perfekt. Irgendwelche Ideen was mache ich falsch?Hinzufügen von Attributen zu einer Zeichenfolge mit Emojis bricht einige Emojis

Hier ist meine Funktion - es sollte fett Zitate (Text zwischen dem ersten und letzten Anführungszeichen)

func boldQuotation(str: String, fontSize: CGFloat) -> NSAttributedString { 
    let normalAttributes = [NSFontAttributeName : UIFont.systemFontOfSize(fontSize)] 
    let boldAttributes = [NSFontAttributeName : UIFont.boldSystemFontOfSize(fontSize)] 
    let attributedStr = NSMutableAttributedString(string: str, attributes: normalAttributes) 

    let firstQuotationMarkRange = str.rangeOfString("\"") 
    let lastQuotationMarkRange = str.rangeOfString("\"", options: [.BackwardsSearch], range: nil, locale: nil) 
    guard let firstIndex = firstQuotationMarkRange?.startIndex, lastIndex = lastQuotationMarkRange?.endIndex else { 
     return attributedStr 
    } 
    attributedStr.addAttributes(boldAttributes, range: NSMakeRange(str.startIndex.distanceTo(firstIndex), firstIndex.distanceTo(lastIndex))) 
    return attributedStr 
} 

Hier Probe von Text, der nicht korrekt zugeordnet werden:

let str = "\"\"" 

Das Ergebnis sieht wie folgt aus:

enter image description here

Ich benutze Swift 2.3, iOS 10.2.1, Xcode 8.2.1, Bereitstellungsziel: 9.3

Antwort

0

Ok, nach weiterer Untersuchung (und keine Antwort) habe ich endlich den Grund und die Lösung dieses Fehlers gefunden.

Es gab ein Problem mit der Erstellung NSRange unter Verwendung von Indizes von Range (erhalten von String). Lange Geschichte kurz - Swift String Bereiche und NSString Bereiche sollten nicht verwendet werden, um eine in eine andere zu konvertieren. Zumindest nicht wie folgt:

let firstQuotationMarkRange  = str.rangeOfString("\"") 
let lastQuotationMarkRange  = str.rangeOfString("\"", options: [.BackwardsSearch], range: nil, locale: nil) 
guard let firstIndex = firstQuotationMarkRange?.startIndex, lastIndex = lastQuotationMarkRange?.endIndex else { 
     return attributedStr 
    } 
//THIS IS WRONG: 
range = NSMakeRange(str.startIndex.distanceTo(firstIndex), firstIndex.distanceTo(lastIndex)) 

Also, was ist die richtige Lösung? Konvertieren Sie zuerst String in NSString und suchen Sie dann nach dem Teilstringbereich. Hier ist festgelegt Funktion:

func boldQuotation(str: String, fontSize: CGFloat) -> NSAttributedString { 
    let normalAttributes = [NSFontAttributeName : UIFont.systemFontOfSize(fontSize)] 
    let boldAttributes = [NSFontAttributeName : UIFont.boldSystemFontOfSize(fontSize)] 
    let attributedStr = NSMutableAttributedString(string: str, attributes: normalAttributes) 

    let nsStr = str as NSString 
    let firstQuotationMarkRange = nsStr.rangeOfString("\"") 
    let lastQuotationMarkRange = nsStr.rangeOfString("\"", options: [.BackwardsSearch]) 
    guard firstQuotationMarkRange.length > 0 && lastQuotationMarkRange.length > 0 else { 
     return attributedStr 
    } 
    let nsrange = NSMakeRange(firstQuotationMarkRange.location, lastQuotationMarkRange.location + lastQuotationMarkRange.length - firstQuotationMarkRange.location) 
    attributedStr.addAttributes(boldAttributes, range: nsrange) 
    return attributedStr 
} 

Gelöst dank diesen Beitrag: NSRange from Swift Range