2013-07-05 9 views
15

To pytanie może być duplikatem this one. Ale odpowiedzi nie działają dla mnie i chcę być bardziej konkretny.Zmiana atrybutów ciągów w NSAttributedString

Mam NSString, ale potrzebuję NS(Mutable)AttributedString, a niektóre słowa w tym ciągu powinny mieć inny kolor. Próbowałem tego:

NSString *text = @"This is the text and i want to replace something"; 

NSDictionary *attributes = @ {NSForegroundColorAttributeName : [UIColor redColor]}; 
NSMutableAttributedString *subString = [[NSMutableAttributedString alloc] initWithString:@"AND" attributes:attributes]; 

NSMutableAttributedString *newText = [[NSMutableAttributedString alloc] initWithString:text]; 

newText = [[newText mutableString] stringByReplacingOccurrencesOfString:@"and" withString:[subString mutableString]]; 

"i" powinny być wielkimi literami i czerwonymi.

Dokumentacja mówi, że mutableString zachowuje odwzorowania atrybutów. Ale z moją rzeczą zastępującą, nie mam więcej attributedString po prawej stronie zadania (w ostatnim wierszu kodu).

Jak mogę uzyskać to, czego chcę? ;)

+0

najpierw zmień ciąg. Następnie utwórz nowy NSMutableAttributedString ze zmienionym ciągiem znaków, a następnie ustaw atrybut jako kolor czerwony. Nie można zmienić ciągu znaków i oczekiwać zachowania atrybutów. – croyneaus4u

Odpowiedz

34

@ Odpowiedź Hyperlorda zadziała, ale tylko wtedy, gdy wystąpi jedno słowo "i" w łańcuchu wejściowym. W każdym razie, na początku używałbym NSString stringByReplacingOccurrencesOfString:, aby zmienić wszystkie "i" na "AND", a następnie użyć trochę wyrażeń regularnych do wykrycia dopasowań w przypisanym łańcuchu i zastosować NSForegroundColorAttributeName w tym zakresie. Oto przykład:

NSString *initial = @"This is the text and i want to replace something and stuff and stuff"; 
NSString *text = [initial stringByReplacingOccurrencesOfString:@"and" withString:@"AND"]; 

NSMutableAttributedString *mutableAttributedString = [[NSMutableAttributedString alloc] initWithString:text]; 

NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(AND)" options:kNilOptions error:nil]; 


NSRange range = NSMakeRange(0,text.length); 

[regex enumerateMatchesInString:text options:kNilOptions range:range usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) { 

    NSRange subStringRange = [result rangeAtIndex:1]; 
    [mutableAttributedString addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:subStringRange]; 
}]; 

Na koniec zastosuj przypisany ciąg do etykiety.

[myLabel setAttributedText:mutableAttributedString]; 
+0

plus 1, ale po co używać wielkich liter "i"? – Jeff

+0

, ponieważ w pytaniu jest napisane "The" i "powinny być wielkie i czerwone". ;-) – Whakkee

+0

Świetne rozwiązanie, dzięki. –

15

myślę, że należy stworzyć NSMutableAttributedString wykorzystaniem istniejącej NSString a następnie dodać styl atrybuty z odpowiednim NSRange w celu kolorowania części, które chcesz podkreślić na przykład:

NSString *text = @"This is the text and i want to replace something"; 
NSMutableAttributedString *mutable = [[NSMutableAttributedString alloc] initWithString:text]; 
[mutable addAttribute: NSForegroundColorAttributeName value:[UIColor redColor] range:[text rangeOfString:@"and"]]; 

mieć świadomość : to jest po prostu z mojej głowy i nie testowałem wcale ;-)

0

Oto kolejna realizacja (Swift) to przydatne, gdy robisz jakieś bardziej skomplikowane operacje (takie jak dodawanie/usuwanie znaków) z przypisaną wyrażenie:

let text = "This is the text and i want to replace something" 
let mutAttrStr = NSMutableAttributedString(string: text) 

let pattern = "\\band\\b" 
let regex = NSRegularExpression(pattern: pattern, options: .allZeros, error: nil) 

while let result = regex!.firstMatchInString(mutAttrStr.string, options: .allZeros, range:NSMakeRange(0, count(mutAttrStr.string)) { 
    let substring = NSMutableAttributedString(attributedString: mutAttrStr.attributedSubstringFromRange(result.range)) 

    // manipulate substring attributes here 
    substring.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor(), range NSMakeRange(0, count(substring.string)) 

    mutAttrStr.replaceCharactersInRange(result.range, withAttributedString: substring) 
} 

Twój ostateczny przypisać ciąg powinien być:

let finalAttrStr = mutAttrStr.copy() as! NSAttributedString 
0

spróbuj tego kodu w Swift 2

var someStr = "This is the text and i want to replace something" 
    someStr.replaceRange(someStr.rangeOfString("and")!, with: "AND") 

    let attributeStr = NSMutableAttributedString(string: someStr) 
    attributeStr.setAttributes([NSForegroundColorAttributeName: UIColor.yellowColor()], range: NSMakeRange(17, 3)) 
    testLbl.attributedText = attributeStr