wake-up-neo.com

Unterstrichene Teile einer Zeichenfolge, die NSMutableAttributedString in iOS 8 verwendet, funktionieren nicht

Ich versuche, einen Teil eines Strings zu unterstreichen, beispielsweise einen ' string ' Teil in ' test string ' string. Ich verwende NSMutableAttributedString und meine Lösung funktionierte gut mit iOS7.

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc]
        initWithString:@"test string"];
[attributedString addAttribute:NSUnderlineStyleAttributeName
                         value:@(NSUnderlineStyleSingle)
                         range:NSMakeRange(5, 6)];
myLabel.attributedText = attributedString;

Das Problem ist, dass meine Lösung nicht mehr in iOS8 funktioniert. Nachdem ich eine Stunde mit dem Testen mehrerer Varianten von NSMutableAttributedString verbracht hatte, stellte ich fest, dass diese Lösung nur funktioniert, wenn der Bereich mit 0 beginnt (die Länge kann variieren). Was ist der Grund dafür? Wie kann ich das umgehen?

56
KlimczakM

Update: Durch Untersuchung dieser Frage: Anzeige von NSMutableAttributedString unter iOS 8 Endlich habe ich die Lösung gefunden!

Sie sollten NSUnderlineStyleNone am Anfang der Zeichenfolge hinzufügen.

Swift 4.2 (none wurde entfernt): 

let attributedString = NSMutableAttributedString()
attributedString.append(NSAttributedString(string: "test ",
                                           attributes: [.underlineStyle: 0]))
attributedString.append(NSAttributedString(string: "s",
                                           attributes: [.underlineStyle: NSUnderlineStyle.single.rawValue]))
attributedString.append(NSAttributedString(string: "tring",
                                           attributes: [.underlineStyle: 0]))

Ziel c:

 NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] init];
 [attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:@"test "
                                                                          attributes:@{NSUnderlineStyleAttributeName: @(NSUnderlineStyleNone)}]];
 [attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:@"s"
                                                                         attributes:@{NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle),
                                                                                      NSBackgroundColorAttributeName: [UIColor clearColor]}]];
 [attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:@"tring"]];

Ein weiterer Vorteil eines solchen Ansatzes ist das Fehlen jeglicher Bereiche. Sehr schön für lokalisierte Saiten.

Scheint, es ist ein Apple-Fehler :(

119
kelin

Ich habe festgestellt, dass Sie, wenn Sie UnderlineStyleNone auf die gesamte Zeichenfolge anwenden, selektiv die Unterstreichung für einen Teil anwenden können, der in der Mitte beginnt:

func underlinedString(string: NSString, term: NSString) -> NSAttributedString {
    let output = NSMutableAttributedString(string: string)
    let underlineRange = string.rangeOfString(term)
    output.addAttribute(NSUnderlineStyleAttributeName, value: NSUnderlineStyle.StyleNone.rawValue, range: NSMakeRange(0, string.length))
    output.addAttribute(NSUnderlineStyleAttributeName, value: NSUnderlineStyle.StyleSingle.rawValue, range: underlineRange)

    return output
}
17
exidy
NSMutableAttributedString *signUpString = [[NSMutableAttributedString alloc] initWithString:@"Not a member yet?Sign Up now"];

[signUpString appendAttributedString:[[NSAttributedString alloc] initWithString:@" "
                                                                         attributes:@{NSUnderlineStyleAttributeName: @(NSUnderlineStyleNone)}]];

[signUpString addAttributes: @{NSForegroundColorAttributeName:UIColorFromRGB(0x43484B),NSUnderlineStyleAttributeName:[NSNumber numberWithInteger:NSUnderlineStyleSingle]} range:NSMakeRange(17,11)];

signUpLbl.attributedText = [signUpString copy];

Es hat für mich funktioniert

6
Tanuj Jagoori

Swift 5-Version von @ Joss 'Antwort mit wenigen Änderungen durch Hinzufügen eines zurückgegebenen NSMutableAttributedString, da ich die ursprüngliche Lösung ohne diese nicht verwenden könnte.

extension NSMutableAttributedString {

func underline(term: String) -> NSMutableAttributedString {
    guard let underlineRange = string.range(of: term) else {
        return NSMutableAttributedString()
    }
    let startPosition = string.distance(from: term.startIndex, to: underlineRange.lowerBound)
    let nsrange = NSRange(location: startPosition, length: term.count)
    addAttribute(
        .underlineStyle,
        value: NSUnderlineStyle.single.rawValue,
        range: nsrange)
     return self
}

}

Verwendungszweck:

 let myUnderLinedText = "Hello World"
 let underLinedMutableString =  NSMutableAttributedString(string: myUnderLinedText, attributes: titleAttributes).underline(term: myUnderLinedText)
0
Mussa Charles

Ich habe die folgende Erweiterung (mit Exidys Funktion) in Spielplatz/Simulator verwendet und es hat gut funktioniert

 extension NSMutableAttributedString
{


    func changeWordsColour(terms:[NSString])
{
    let string = self.string as NSString
    self.addAttribute(NSForegroundColorAttributeName, value: UIColor.brownColor(), range: NSMakeRange(0, self.length))
    for term in terms
    {
        let underlineRange = string.rangeOfString(term as String)
        self.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor(), range: underlineRange)

    }
}
}

 let myStr = NSMutableAttributedString(string: "Change Words Colour")
 myStr.changeWordsColour(["change","Colour"])
0
Atka

Es ist September 2018, also geht es bei dieser Antwort nicht um iOS8, aber es bezieht sich immer noch auf das Unterstreichen eines Teils einer Zeichenfolge.

Hier ist eine Swift 4 -Erweiterung, die einen bestimmten Begriff innerhalb einer bereits erstellten myAttributedString unterstreicht

extension NSMutableAttributedString {

    func underline(term: String) {

        guard let underlineRange = string.range(of: term) else {

            return
        }

        let startPosition = string.distance(from: term.startIndex, to: underlineRange.lowerBound)
        let nsrange = NSRange(location: startPosition, length: term.count)

        addAttribute(
            .underlineStyle,
            value: NSUnderlineStyle.styleSingle.rawValue,
            range: nsrange)
    }
}

Verwendung: myAttributedString.underline(term: "some term")

0
Joss