Подтвердить что ты не робот

Изменение атрибутов подстрок в 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 в правой части задания (в последней строке моего кода-фрагмента).

Как я могу получить то, что хочу?;)

4b9b3361

Ответ 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