Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you clear attributes from NSMutableAttributedString?

How do you set all the attributes in an NSMutableAttributedString to nothing? Do you have to enumerate through them and remove them?

I don't want to create a new one. I am working on the textStorage in NSTextView. Setting a new string resets the cursor position in NSTextView and fires the delegate.

like image 227
James Alvarez Avatar asked Mar 05 '15 14:03

James Alvarez


2 Answers

You can remove all of the attributes like this:

NSMutableAttributedString *originalMutableAttributedString = //your string…

NSRange originalRange = NSMakeRange(0, originalMutableAttributedString.length);
[originalMutableAttributedString setAttributes:@{} range:originalRange];

Note that this uses setAttributes (not add). From the docs:

These new attributes replace any attributes previously associated with the characters in aRange.

If you need to do any of it conditionally, you could also enumerate the attributes and remove them one-by-one:

[originalMutableAttributedString enumerateAttributesInRange:originalRange
                                                    options:kNilOptions
                                                 usingBlock:^(NSDictionary *attrs, NSRange range, BOOL *stop) {
                                                        [attrs enumerateKeysAndObjectsUsingBlock:^(NSString *attribute, id obj, BOOL *stop) {
                                                            [originalMutableAttributedString removeAttribute:attribute range:range];
                                                        }];
                                                    }];

According to the docs this is allowed:

If this method is sent to an instance of NSMutableAttributedString, mutation (deletion, addition, or change) is allowed.


Swift 2

If string is a mutable attributed string:

string.setAttributes([:], range: NSRange(0..<string.length))

And if you want to enumerate for conditional removal:

string.enumerateAttributesInRange(NSRange(0..<string.length), options: []) { (attributes, range, _) -> Void in
    for (attribute, object) in attributes {
        string.removeAttribute(attribute, range: range)
    }
}
like image 152
Aaron Brager Avatar answered Nov 29 '22 10:11

Aaron Brager


swift 4:

I needed to remove the attributes from a textview in a reusable cell, they were transferred from one cell to another if the other was using the text property, so the text instead being only a text it was with the attributes from the previous cell. Only this worked for me, inspired by the accepted answer above:

iOS

let attr = NSMutableAttributedString(attributedString: (cell.textView?.attributedText)!)
    let originalRange = NSMakeRange(0, attr.length)
    attr.setAttributes([:], range: originalRange)
    cell.textView?.attributedText = attr
    cell.textView?.attributedText = NSMutableAttributedString(string: "", attributes: [:])
    cell.textView?.text = ""

macOS

textView.textStorage?.setAttributedString(NSAttributedString(string: ""))
like image 32
Cristi Băluță Avatar answered Nov 29 '22 10:11

Cristi Băluță