Изменение атрибутов подстрок в NSAttributedString
Этот вопрос может быть дубликатом этого. Но ответы не работают для меня, и я хочу быть более конкретным.
У меня есть NSString
, но мне нужен NS(Mutable)AttributedString
, и некоторые слова в этой строке должны иметь другой цвет. Я пробовал это:
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]];
"и" должно быть в верхнем регистре красным.
В документации указано, что mutableString сохраняет сопоставления атрибутов. Но с моей заменой, у меня больше нет атрибутаString в правой части задания (в последней строке моего кода-фрагмента).
Как я могу получить то, что хочу?;)
Ответы
Ответ 1
@Ответ на гиперпользователь будет работать, но только если в строке ввода есть одно слово "и". Во всяком случае, то, что я сделал бы, это сначала использовать NSString stringByReplacingOccurrencesOfString:
, чтобы изменить каждый "и" на "И", а затем использовать небольшое регулярное выражение для определения совпадений в атрибутной строке и применить NSForegroundColorAttributeName
в этом диапазоне. Вот пример:
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];
}];
И, наконец, просто примените присваиваемую строку к вашей метке.
[myLabel setAttributedText:mutableAttributedString];
Ответ 2
Я думаю, вы должны создать NSMutableAttributedString
с помощью существующего NSString
, а затем добавить атрибуты стиля с соответствующим NSRange
, чтобы раскрасить те части, которые вы хотите подчеркнуть, например:
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"]];
Знайте: это только с моей головы и не проверено вообще; -)
Ответ 3
Здесь другая реализация (в Swift), которая полезна, если вы выполняете более сложные манипуляции (например, добавление/удаление символов) с вашей атрибутной строкой:
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)
}
Ваша окончательная атрибутная строка должна быть:
let finalAttrStr = mutAttrStr.copy() as! NSAttributedString
Ответ 4
Пожалуйста, попробуйте этот код в 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