Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSTextAttachment custom view

Is it possible to display a custom view in the spot where an NSTextAttachment is to be displayed on iOS? I have custom text storage and layout manager subclasses, but I'm not sure where to put the code to actually add a subview.

(The reason I want to have this is to support inline equation editing. I have a custom text field class which will allow the user to type an equation, and I want this view to be added inside the body of another text view.)

I've seen this tutorial, and while it seems like a good starting place it doesn't cover where the text attachment is actually drawn. So, specifically, what methods should I override to add a custom view in place of the default text attachment icon?

Please let me know if what I want to do is possible, or whether I'm going about this the wrong way. Thanks for your help!

like image 575
architectpianist Avatar asked May 25 '14 23:05

architectpianist


1 Answers

What you want to do is possible, albeit not directly foreseen by the framework architecture. Text attachments are designed as sort-of passive elements that are part of the text and do not expose any special or separate interaction. Essentially they are just drawing objects. But… if you know how the layout process works, you can plug in your custom views.

To update the layout with every relevant change, you will need to overwrite this method and position the views on every call:

- (void)drawGlyphsForGlyphRange:(NSRange)glyphsToShow atPoint:(NSPoint)origin 

Since this is called very often, make sure it's implementation is sufficiently efficient. It should be safe to also insert and remove views during a call of this method, as well as change the frame of the respective views. Get the character range for the glyph range like so:

NSRange charRange = [self characterRangeForGlyphRange:glyphRange actualGlyphRange:NULL];

Next, iterate through your custom storage to find all formula attachments. For each of these attachments, get the glyph's layout boundaries from the layout manager, e.g. using this method:

- (NSRect)boundingRectForGlyphRange:(NSRange)glyphRange inTextContainer:(NSTextContainer *)container

Then update the view's frame to the returned rect and take it from there.

like image 120
Max Seelemann Avatar answered Sep 19 '22 01:09

Max Seelemann