iosobjective-cswiftnsattributedstring

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.


Solution

  • 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)
        }
    }