nstextviewnsattributedstring

NSTextView not applying attributes to newly inserted text


I have an NSTExtView and am setting attribues for certain ranges of text using [theTextView.textStorage addAttribute: value: range:]

For example, I highlight a range using [theTextView.textStorage addAttribute:NSBackgroundColorAttributeName value:[NSColor yellowColor] range:theSelectedRange];

The problem is that when I manually type new text into that range, it is not highlighted. It splits the highlighted range into 2 ranges and beings inserting non-highlighted text between them. Is there a way to make the newly inserted text also be highlighted?


Solution

  • When the user types something new into your NSTextView, the insertion point is using whatever attributes (if any) are associated with the current font. This is also referred to as the "typingAttributes" of a text view. In most cases, the user is going to be typing with a black color and a white background.

    Now since you're highlighting (and not doing a selection), what you need to do is to pick up the current color at the cursor's insertion point.

    You can do that via fetching the attributes via:

    // I think... but am not 100% certain... the selected range
    // is the same as the insertion point.
    NSArray * selectedRanges = [theTextView selectedranges];
    if(selectedRanges && ([selectedRanges count] > 0))
    {
        NSValue * firstSelectionRangeValue = [selectedRanges objectAtIndex: 0];
        if(firstSelectionRangeValue)
        {
            NSRange firstCharacterOfSelectedRange = [firstSelectionRangeValue rangeValue];
    
            // now that we know where the insertion point is likely to be, let's get
            // the attributes of our text
            NSSDictionary * attributesDictionary = [theTextView.textStorage attributesAtIndex: firstCharacterOfSelectedRange.location effectiveRange: NULL];
    
            // set these attributes to what is being typed
            [theTextView setTypingAttributes: attributesDictionary];
    
            // DON'T FORGET to reset these attributes when your selection changes, otherwise
            // your highlighting will appear anywhere and everywhere the user types.
        }
    }
    

    I haven't tested or tried out this code at all, but this should get you to where you need to be.