I'm not sure what I'm doing wrong. I have a NSTextView and am registered as the delegate for its textStorage attribute. When I receive -textStorageDidProcessEditing:notification:
I'm trying to apply attributes to ranges of characters within the text. It certainly does "something" to the characters, but not what I expect... they just disappear!
A heavily distilled code example. This should make sure the second character in the text field is always red:
-(void)textStorageDidProcessEditing:(NSNotification *)notification {
NSTextStorage *textStorage = [textView textStorage];
if ([[textStorage string] length] > 1) {
NSColor *color = [NSColor redColor];
NSDictionary *attributes = [NSDictionary dictionaryWit开发者_Python百科hObjectsAndKeys:color, NSForegroundColorAttributeName, nil];
[textStorage setAttributes:attributes range:NSMakeRange(1, 1)];
}
}
Instead, as I type the sequence "abcdefg" I get "a", then when I hit "b" seemingly nothing happens, then when I hit "cdefg" typing occurs as normal, making the end result "acdefg"... the "b" is missing!
If I start hitting backspace I have to hit backspace 7 times, as if the "b" is actually there, but just not being drawn (cursor stalls as it deletes the "b", then on the next backspace deletes the "a" as expected).
If I apply attributes to some default text in the view using the same -setAttributes:range:
method before the view is drawn then it does exactly as I expect.
Any clues? It seems like a fairly normal use of a NSTextStorageDelegate
:)
I've tried calling -setNeedsDisplay
on the text field to no avail.
Figured it out. Using NSTextStorage's -addAttribute:value:range
works. I still don't fully understand why but at least I can get over it and move on.
-(void)textStorageDidProcessEditing:(NSNotification *)notification {
// ... SNIP ...
[textStorage addAttribute:NSForegroundColorAttributeName
value:[NSColor redColor]
range:NSMakeRange(1, 1)];
}
Makes the code a bit less cluttered too.
I'm not sure how relevant this is for you after so many years but I think the reason for it was that you were setting attributes with a dictionary which does not contain NSFontAttributeName
, effectively removing it from the textview.
So I think this should work:
-(void)textStorageDidProcessEditing:(NSNotification *)notification {
NSTextStorage *textStorage = [textView textStorage];
if ([[textStorage string] length] > 1) {
NSColor *color = [NSColor redColor];
NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:color, NSForegroundColorAttributeName, [NSFont ...whatever...], NSFontAttributeName, nil];
[textStorage setAttributes:attributes range:NSMakeRange(1, 1)];
}
}
精彩评论