5

I have an MSMutableAttributedString displayContent. The attributes of the content vary across the string i.e. the colours and font sizes can vary by letter.

I want to add a new character to the end of the string and for it to pick up the attributes of the last character in displayContent. I cannot know what those attributes are in advance since they are under user control.

When I append the new character (tempAttr):

NSAttributedString * tempAttr = [[NSAttributedString alloc] initWithString:appendage];
[displayContent appendAttributedString:tempAttr];

it appears to reset the attributes of the whole string to the attributes of the new character (which I haven't set since I can't know what they need to be).

How do I get tempAttr to pick up the attributes of the last character in displayContent? Thanks.


Update. Made progress on this in a clumsy but functional way. Copy the attributes dictionary from the last character in the display (displayContent) and then reapply those attributes to the new character being added:

NSMutableDictionary * lastCharAttrs = [NSMutableDictionary dictionaryWithCapacity:5];
[lastCharAttrs addEntriesFromDictionary: [displayContent attributesAtIndex:0 
                                                            effectiveRange:NULL]]; // get style of last letter
NSMutableAttributedString * tempAttr = [[NSMutableAttributedString alloc] initWithString:newCharacter 
                                                                              attributes:lastCharAttrs];

[displayContent appendAttributedString:tempAttr]; // Append to content in the display field

I would have hoped there was a more elegant way to do this like setting a property of the NSTextField.

1 Answer 1

14

I think I discovered a solution to this by accident, then found this page while looking for the answer to the problem I created for myself (the opposite of your issue).

If you do the following:

[[displayContent mutableString] appendString:newCharacter];

You'll end up with newCharacter appended and the previous attributes "stretched" to cover it. I cannot find this behavior documented anywhere, however, so you might be weary of counting on it.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks a lot for the post. I substituted your line into the code and it worked fine. Thank you. Any insight into why this works? The mutableString method returns simply the string contents of the attributedString. Doc mentions nothing about the attributes themselves getting copied across. So, I don't see where the appendedString picks up the right attributes from.
I haven no idea. I can’t decide if it’s an implementation detail (i.e. a side-effect/behavior that may change) or if it’s actual intended behavior. But thinking about it as opposed to “appendAttributedString:” which obviously has its own attributes, I could see reasoning that extending the underlying string should cause the attributes to carry over. That said, how it’s actually plumbed together, I have no idea.
@BenCochran You're right that there's nothing specifically mentioned about the attributes stretching, but the docs do say: The receiver tracks changes to this string and keeps its attribute mappings up to date. That seems to be what is occurring.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.