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

Заменить подстроку NSAttributedString на другую NSAttributedString

Я хочу заменить подстроку (например, @"replace") NSAttributedString на другую NSAttributedString.

Я ищу эквивалентный метод NSString stringByReplacingOccurrencesOfString:withString: для NSAttributedString.

4b9b3361

Ответ 1

  • Преобразуйте присланную строку в экземпляр NSMutableAttributedString.

  • Измененная строка с атрибутом имеет свойство mutableString. Согласно документации:

    "Приемник отслеживает изменения этой строки и сохраняет их отображения атрибутов в актуальном состоянии".

    Таким образом, вы можете использовать полученную переменную строку для выполнения замены с помощью replaceOccurrencesOfString:withString:options:range:.

Ответ 2

Вот как вы можете изменить строку NSMutableAttributedString, сохраняя при этом ее атрибуты:

Swift:

// first we create a mutable copy of attributed text 
let originalAttributedText = nameLabel.attributedText?.mutableCopy() as! NSMutableAttributedString

// then we replace text so easily
let newAttributedText = originalAttributedText.mutableString.setString("new text to replace")

Objective-C:

NSMutableAttributedString *newAttrStr = [attribtedTxt.mutableString setString:@"new string"];

Ответ 3

В моем случае, единственный способ был протестирован на iOS9:

NSAttributedString *attributedString = ...;
NSAttributedString *anotherAttributedString = ...; //the string which will replace

while ([attributedString.mutableString containsString:@"replace"]) {
        NSRange range = [attributedString.mutableString rangeOfString:@"replace"];
        [attributedString replaceCharactersInRange:range  withAttributedString:anotherAttributedString];
    }

Конечно, было бы неплохо найти другой лучший способ.

Ответ 4

Мне нужно было выделить текст в тегах <b>, вот что я сделал:

- (NSAttributedString *)boldString:(NSString *)string {
    UIFont *boldFont = [UIFont boldSystemFontOfSize:14];
    NSMutableAttributedString *attributedDescription = [[NSMutableAttributedString alloc] initWithString:string];

    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@".*?<b>(.*?)<\\/b>.*?" options:NSRegularExpressionCaseInsensitive error:NULL];
    NSArray *myArray = [regex matchesInString:string options:0 range:NSMakeRange(0, string.length)] ;
    for (NSTextCheckingResult *match in myArray) {
        NSRange matchRange = [match rangeAtIndex:1];
        [attributedDescription addAttribute:NSFontAttributeName value:boldFont range:matchRange];
    }
    while ([attributedDescription.string containsString:@"<b>"] || [attributedDescription.string containsString:@"</b>"]) {
        NSRange rangeOfTag = [attributedDescription.string rangeOfString:@"<b>"];
        [attributedDescription replaceCharactersInRange:rangeOfTag withString:@""];
        rangeOfTag = [attributedDescription.string rangeOfString:@"</b>"];
        [attributedDescription replaceCharactersInRange:rangeOfTag withString:@""];
    }
    return attributedDescription;
}

Ответ 5

С Swift 4 и iOS 11 вы можете использовать один из двух способов, чтобы решить вашу проблему.


# 1. Используя метод NSMutableAttributedString replaceCharacters(in:with:)

NSMutableAttributedString имеет метод replaceCharacters(in:with:). replaceCharacters(in:with:) имеет следующее объявление:

Заменяет символы и атрибуты в заданном диапазоне символами и атрибутами данной атрибутной строки.

func replaceCharacters(in range: NSRange, with attrString: NSAttributedString)

Ниже приведен пример кода игры, где показано, как использовать replaceCharacters(in:with:) для замены подстроки экземпляра NSMutableAttributedString новым экземпляром NSMutableAttributedString:

import UIKit

// Set initial attributed string
let initialString = "This is the initial string"
let attributes = [NSAttributedStringKey.foregroundColor : UIColor.red]
let mutableAttributedString = NSMutableAttributedString(string: initialString, attributes: attributes)

// Set new attributed string
let newString = "new"
let newAttributes = [NSAttributedStringKey.underlineStyle : NSUnderlineStyle.styleSingle.rawValue]
let newAttributedString = NSMutableAttributedString(string: newString, attributes: newAttributes)

// Get range of text to replace
guard let range = mutableAttributedString.string.range(of: "initial") else { exit(0) }
let nsRange = NSRange(range, in: mutableAttributedString.string)

// Replace content in range with the new content
mutableAttributedString.replaceCharacters(in: nsRange, with: newAttributedString)

# 2. Использование метода NSMutableString replaceOccurrences(of:with:options:range:)

NSMutableString имеет метод replaceOccurrences(of:with:options:range:). replaceOccurrences(of:with:options:range:) имеет следующее объявление:

Заменяет все вхождения данной строки в заданном диапазоне другой заданной строкой, возвращая количество замен.

func replaceOccurrences(of target: String, with replacement: String, options: NSString.CompareOptions = [], range searchRange: NSRange) -> Int

Ниже приведен пример кода игры, где показано, как использовать replaceOccurrences(of:with:options:range:) для замены подстроки экземпляра NSMutableAttributedString новым экземпляром NSMutableAttributedString:

import UIKit

// Set initial attributed string
let initialString = "This is the initial string"
let attributes = [NSAttributedStringKey.foregroundColor : UIColor.red]
let mutableAttributedString = NSMutableAttributedString(string: initialString, attributes: attributes)

// Set new string
let newString = "new"

// Replace replaceable content in mutableAttributedString with new content
let totalRange = NSRange(location: 0, length: mutableAttributedString.string.count)
_ = mutableAttributedString.mutableString.replaceOccurrences(of: "initial", with: newString, options: [], range: totalRange)

// Get range of text that requires new attributes
guard let range = mutableAttributedString.string.range(of: newString) else { exit(0) }
let nsRange = NSRange(range, in: mutableAttributedString.string)

// Apply new attributes to the text matching the range
let newAttributes = [NSAttributedStringKey.underlineStyle : NSUnderlineStyle.styleSingle.rawValue]
mutableAttributedString.setAttributes(newAttributes, range: nsRange)

Ответ 6

NSMutableAttributedString *result = [[NSMutableAttributedString alloc] initWithString:@"I am a boy."];
[result addAttribute:NSForegroundColorAttributeName value:[UIColor blackColor] range:NSMakeRange(0, [result length])];

NSMutableAttributedString *replace = [[NSMutableAttributedString alloc] initWithString:@"a"];
[replace addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0, [replace length])];

[result replaceCharactersInRange:NSMakeRange(5, [replace length]) withAttributedString:replace];

Ответ 7

Я считаю, что все остальные ответы не работают. Вот как я заменил содержимое строки NSAttributed в расширении категории:

func stringWithString(stringToReplace:String, replacedWithString newStringPart:String) -> NSMutableAttributedString
{
    let mutableAttributedString = mutableCopy() as! NSMutableAttributedString
    let mutableString = mutableAttributedString.mutableString

    while mutableString.containsString(stringToReplace) {
        let rangeOfStringToBeReplaced = mutableString.rangeOfString(stringToReplace)
        mutableAttributedString.replaceCharactersInRange(rangeOfStringToBeReplaced, withString: newStringPart)
    }
    return mutableAttributedString
}