Here you go:
https://developer.apple.com/documentation/uikit/textkit/enriching_your_text_in_text_views
There's not much meat in there, unfortunately, and the lists are very buggy (on macOS, try clicking at the end of a line).
It also seems there's a lot of stuff not yet available in the first Ventura/Xcode 14 beta. For instance, the NS/UITextView constructor init(usingTextLayoutManager:) seems to be missing.
Post
Replies
Boosts
Views
Activity
Yes, TextKit 2 is built using Core Text, as is Text Kit 1. This is mentioned in the WWDC 21 video "Meet TextKit 2".
https://developer.apple.com/documentation/uikit/textkit/enriching_your_text_in_text_views
It is a little strange that UITextView doesn't have a convenience property for this. However, you can still access it easily enough via the textLayoutManager's .textContentManager property (NSTextContentStorage being the concrete subclass of NSTextContentManager used by NS/UITextView). And of course you could create an extension to UITextView to add the .textContentStorage property yourself:
extension UITextView {
var textContentStorage: NSTextContentStorage? {
return textLayoutManager?.textContentManager as? NSTextContentStorage
}
}
Hopefully Apple will add this, though, as it would be useful. (I've filed an enhancement request: #FB10376167.)
Overriding NSTextLayoutFragment.draw(at:in:) in an NSTextLayoutFragment subclass provided by the NSTextLayoutManagerDelegate is indeed the designated way of doing custom drawing now. However, note that it still doesn't have quite the same effect as NSLayoutManager.drawBackground(forGlyphRange:at:). While you can draw behind the text by doing your custom drawing before calling super.draw(at: point, in: context), all custom drawing in NSTextLayoutFragment is still done above text text view's selection (in NSTextView anyway). In NSLayoutManager, drawing done in drawBackground(forGlyphRange:at:) was done beneath the text selection, which could be useful for some elements. There seems to be no way of doing the same in TextKit 2 just yet. (I filed this as #FB10159592 but received a fairly standard dismissive reply).
You can also do custom drawing in NSTextView's drawBackround(in:), but that's more awkward because calculating the visible ranges is expensive.
For custom interaction, I suppose it depends on what you're trying to do. You could do it in a text view subclass and use NSTextLayoutManager's various methods to get the frames of the text you need. For instance, I allow live image resizing in an NSTextView, and draw resizing handles over image text attachments. For that I can use NSTextLayoutManager's layoutFragment(for: point) in mouseDown(_:), converting the point from text view to text container coordinates, and I can then get the image frame using NSTextLayoutFragment.frameForTextAttachment(at:), and add a new sublayer to the text view to draw my resizing handles. There are a couple of gotchas here, though:
Because NSTextView (and presumably UITextView) in TextKit 2 does all of its drawing using layers, you have to set the z position of any new sublayer you add to something high (e.g.FLT_MAX).
The coordinate system used for TextKit 2 is so far undocumented, and seems pretty strange. NSTextLayoutFragment.layoutFragmentFrame is straightforward, being in text container coordinates, and NSTextLayoutFragment.renderingSurfaceBounds is relative to that (although the docs say its coordinates are flipped compared to layoutFragmentFrame, when they don't seem to be). However, both NSLayoutFragment.frameForTextAttachment(at:) and NSTextLineFragment.typographicBounds seem to be relative to NSTextLayoutFragment.layoutFragmentFrame vertically, but relative to the text container horizontally. (And there are also some issues with the frames being narrower than you'd expect when using overlay scroll bars.)
I'm not sure how helpful that is to what you want to do.
This bug has been around for a long time. I first reported it to Apple back in 2016 (radar ID 25220931; updated #FB6001878 last year).
In my app, I make it so that you can have a large gap below the text you are writing, so that the text is not always at the bottom of the editor (like in Xcode). I was initially using a large bottom textContainerInset to achieve this, but this triggered the selection scrolling bug you describe.
My workaround is to leave the bottom textContainerInset alone and to instead increase the contentSize height in a UITextView subclass. (I add the extra height whenever the contentSize is set in the subclass override.)
This really only works for adding space below, though. To add space above, as you want, you'd need to mess with contentInset, but doing so causes the same selection scrolling problem as adjusting the textContainerInset so unfortunately gets you nowhere.
In your situation I think the only solution is to push the entire top of the text view down to make space for the comment, even though that might not be ideal, as presumably you wanted the text view visible and scrollable beneath the comment.