Genmoji is there but doesn't display in NSTextView

I have discovered an odd issue with NSTextView, NSAdaptiveImageGlyph, and NSLayoutManager.

(Forgive the Objective-C... I'm old-school.)

I can easily display an attributed string containing text and Genmoji NSAdaptiveImageGlyphs with something very basic like this:

textView = [[NSTextView alloc] initWithFrame:NSMakeRect(100.0, 100.0, 500.0, 100.0)];
[textView.textStorage setAttributedString:sampleText];
[self addSubview:textView];
//NSLayoutManager *layoutManager = textView.layoutManager;

I can even insert or paste new Genmoji into there as well.

However, if I uncomment out that last line to retrieve the layoutManager of the text view it breaks the rendering of Genmoji, even if I do nothing with the layoutManager! Just getting it causes the NSTextView to skip past Genmoji glyphs when spacing out glyphs and when rendering.

I thought perhaps getting the layoutManager caused an internal cache to break so I tried ensureLayoutForTextContainer but that didn't help.

Interestingly if I paste a new Genmoji into the NSTextView it doesn't display either. Yet if I select all, copy, and paste into TextEdit I see all the Genmoji just fine so they are there, just invisible and zero size. Using the arrow keys I have to skip past the invisible Genmoji.

But if I comment out that line again I see all Genmoji with no issues.

I do need to use a layoutManager to measure things like text bounds and heights. Elsewhere in the code, my existing drawing routines would like to draw the resulting attributed string not with drawAtPoint (which works fine) but with drawGlyphsForGlyphRange but that doesn't work either as it uses NSLayoutManager.

Is there a trick to getting NSAdaptiveImageGlyphs working with NSLayoutManager?

Thanks for any assistance!

Answered by DTS Engineer in 823240022

As @pnowell said, when you access textView.layoutManager, the text view falls back to TextKit1, and that triggers the issue you described.

NSAdaptiveImageGlyph isn't supposed to work with TextKit1. If possible, you might consider adopting TextKit2 in your app, which I think is the best way to fix the issue.

If you can't adopt TextKit2 just yet, consider grabbing the image data from NSAdaptiveImageGlyph and converting it to NSTextAttachment, which is well supported in TextKit1.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Perhaps that’s because NSLayoutManager is a TextKit 1 API, and accessing it converts everything to TextKit 1. I wouldn’t be surprised if the new Genmoji/NSAdaptiveImageGlyph API only supports TextKit 2. The TextKit 2 replacement for NSLayoutManager is NSTextLayoutManager.

Accepted Answer

As @pnowell said, when you access textView.layoutManager, the text view falls back to TextKit1, and that triggers the issue you described.

NSAdaptiveImageGlyph isn't supposed to work with TextKit1. If possible, you might consider adopting TextKit2 in your app, which I think is the best way to fix the issue.

If you can't adopt TextKit2 just yet, consider grabbing the image data from NSAdaptiveImageGlyph and converting it to NSTextAttachment, which is well supported in TextKit1.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Thank you both for the quick responses. I didn't realize it was only supported by TextKit 2. I'll see what it would take to migrate everything to TK2.

Genmoji is there but doesn't display in NSTextView
 
 
Q