问题
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:
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
:
来源:https://stackoverflow.com/questions/55208022/which-replacement-method-is-called-when-editing-an-attributed-string