Which replacement method is called when editing an

2019-07-26 04:11发布

NSMutableAttributedString defines two string replacement methods:

func replaceCharacters(in range: NSRange, 
                       with str: String)

and

func replaceCharacters(in range: NSRange, 
                with attrString: NSAttributedString)

I have created a subclass of NSTextStorage which in its turn is a subclass of NSMutableAttributedString. In that subclass I overrode both of the above methods.

To my surprise, the latter method (which passes an attributed replacement string) is never called when I type or paste something in my text view. It's only the plain string replacement method that gets called each time.

This leads me to the question:
Based on which rules are these two methods actually called, when the user is editing the text in a text view?

(I need to perform different operations in my text storage, depending on whether the attributed replacement string contains a specific kind of text attachment. But if the replacement method for the attributed string is never called, I see no way how to make this distinction.

1条回答
劫难
2楼-- · 2019-07-26 04:51

Function

func replaceCharacters(in range: NSRange, 
                with attrString: NSAttributedString)

is actually never called.

From documentation (below) it is clear that one should use combination of replaceCharactersInRange:withString: followed by a call setAttributes:range:

/* Note for subclassing NSTextStorage: NSTextStorage is a semi-abstract subclass of NSMutableAttributedString. It implements change management (beginEditing/endEditing), verification of attributes, delegate handling, and layout management notification. The one aspect it does not implement is the actual attributed string storage --- this is left up to the subclassers, which need to override the two NSMutableAttributedString primitives in addition to two NSAttributedString primitives:

  • (NSString *)string;
  • (NSDictionary *)attributesAtIndex:(NSUInteger)location effectiveRange:(NSRangePointer)range;

  • (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)str;

  • (void)setAttributes:(NSDictionary *)attrs range:(NSRange)range; These primitives should perform the change then call edited:range:changeInLength: to get everything else to happen. */

Make sure you have custom implementation of these methods.

And this is also how AppKit implements NSTextView:

enter image description here

查看更多
登录 后发表回答