Replace substring NSAttributedString with another NSAttributedString

I want to replace a substring (e.g. @"replace" ) of NSAttributedString with another NSAttributedString .

I am looking for an equivalent NSString method stringByReplacingOccurrencesOfString:withString: for NSAttributedString .

+45
string replace cocoa foundation nsattributedstring
Nov 22 2018-11-11T00:
source share
7 answers
  • Convert the sent string to an instance of NSMutableAttributedString .

  • The modified attribute string has the mutableString property. According to the documentation:

    "The receiver tracks the changes to this line and keeps their attribute mappings up to date."

    Thus, you can use the resulting variable string to perform a replacement with replaceOccurrencesOfString:withString:options:range:

+61
Nov 22 '11 at 18:05
source share

Here's how you can change the NSMutableAttributedString string while maintaining its attributes:

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"]; 
+18
Jun 05 '13 at 2:47
source share

In my case, the only way was tested on 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]; } 

Of course, it would be nice to find another better way.

+13
Mar 25 '16 at 8:30
source share

I needed to highlight the text in the <b> tags, here is what I did:

 - (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; } 
+3
Nov 24 '15 at 12:06
source share

With Swift 4 and iOS 11, you can use one of two ways to solve your problem.




# 1. Using the NSMutableAttributedString replaceCharacters(in:with:) method

NSMutableAttributedString has a replaceCharacters(in:with:) method. replaceCharacters(in:with:) has the following declaration:

Replaces characters and attributes in a given range with the characters and attributes of this attribute string.

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

The following is a sample game code that shows how to use replaceCharacters(in:with:) to replace a substring of an NSMutableAttributedString instance NSMutableAttributedString new NSMutableAttributedString instance:

 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. Using the NSMutableString replaceOccurrences(of:with:options:range:) method

NSMutableString has a replaceOccurrences(of:with:options:range:) method. replaceOccurrences(of:with:options:range:) has the following declaration:

Replaces all occurrences of a given string in a given range with another specified string, returning the number of replacements.

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

The following is a sample game code that shows how to use replaceOccurrences(of:with:options:range:) to replace a substring of an NSMutableAttributedString instance NSMutableAttributedString new NSMutableAttributedString instance:

 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) 
+3
Aug 03 '17 at 15:11
source share
 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]; 
+2
Apr 12 '14 at 11:15
source share

I believe that all other answers do not work. Here's how I replaced the contents of the NSAttributed string in the category extension:

 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 } 
+1
Jul 31 '16 at 10:09
source share



All Articles