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?
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 :(
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
}
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
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)
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"])
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")