Замените подстроку NSAttributedString другой NSAttributedString
Я хочу заменить подстроку (например,@"replace"
) из NSAttributedString
С другой NSAttributedString
.
Я ищу эквивалентный метод для NSString
' s stringByReplacingOccurrencesOfString:withString:
на NSAttributedString
.
9 ответов
преобразуйте приписываемую строку в экземпляр
NSMutableAttributedString
.-
мутабельном отнести строке
mutableString
собственность. Согласно документации:"приемник отслеживает изменения в этой строке и сохраняет свои сопоставления атрибутов в актуальном состоянии."
таким образом, вы можете использовать полученную изменяемую строку для выполнения замены на
replaceOccurrencesOfString:withString:options:range:
.
вот как вы можете изменить строку NSMutableAttributedString, сохраняя при этом ее атрибуты:
Свифт:
// 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")
Цель-C:
NSMutableAttributedString *newAttrStr = [attribtedTxt.mutableString setString:@"new string"];
в моем случае единственным (проверенным на 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];
}
конечно, будет неплохо найти другой лучший способ.
С Swift 4 и iOS 11, вы можете использовать 2 следующим образом для того, чтобы решить вашу проблему.
#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)
мне пришлось жирным шрифтом в <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;
}
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];
Я нахожу, что все остальные ответы не работают. Вот как Я заменил содержимое строки 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
}
Swift 4: Обновлено sunkas превосходное разрешение к Swift 4 и обернуто в "выдвижении". Просто закрепите это в своем ViewController (вне класса) и используйте его.
extension NSAttributedString {
func stringWithString(stringToReplace: String, replacedWithString newStringPart: String) -> NSMutableAttributedString
{
let mutableAttributedString = mutableCopy() as! NSMutableAttributedString
let mutableString = mutableAttributedString.mutableString
while mutableString.contains(stringToReplace) {
let rangeOfStringToBeReplaced = mutableString.range(of: stringToReplace)
mutableAttributedString.replaceCharacters(in: rangeOfStringToBeReplaced, with: newStringPart)
}
return mutableAttributedString
}
}
У меня есть конкретное требование и исправлено, как показано ниже. Это может кому-то помочь.
требования: в раскадровке богатый текст непосредственно добавлен в атрибут UITextView, который содержит слово "версия приложения: 1.0". Теперь я должен динамизировать номер версии, прочитав его из info plist.
устранение: Удалил номер версии 1.0 из раскадровки, просто сохранил "версию приложения:" и добавил ниже код.
NSAttributedString *attribute = self.firsttextView.attributedText;
NSMutableAttributedString *mutableAttri = [[NSMutableAttributedString alloc] initWithAttributedString:attribute];
NSString *appVersionText = @"App Version:";
if ([[mutableAttri mutableString] containsString:appVersionText]) {
NSDictionary* infoDict = [[NSBundle mainBundle] infoDictionary];
NSString* version = [infoDict objectForKey:@"CFBundleShortVersionString"];
NSString *newappversion = [NSString stringWithFormat:@"%@ %@",appVersionText,version] ;
[[mutableAttri mutableString] replaceOccurrencesOfString:appVersionText withString:newappversion options:NSCaseInsensitiveSearch range:NSMakeRange(0, mutableAttri.length)];
self.firsttextView.attributedText = mutableAttri;
}
готово!! Обновлено / изменено attributedText.