How to override NSTextLayoutFragment.textLineFragments properly?

I am trying to add custom attributes on-the-fly. To make it work, I subclassed NSTextLayoutFragment, and overrode .textLineFragments property to return custom made NSTextLineFragment objects.

But if I override it, TextKit2 no longer render the text and selection also doesn't work. It's same even if provide NSTextLineFragment with exactly same properties (attributed string and range). In WWDC 22 video, you told me that NSTextLayoutFragment and NSTextLineFragment are all immutable and have value semantics. But it doesn't work with different object, therefore seems still have very strong reference semantics.

How to make it work with custom attributes?

P.S. I also reported this as a feedback -- https://feedbackassistant.apple.com/feedback/12443016

Post not yet marked as solved Up vote post of Eonil Down vote post of Eonil
888 views

Replies

Greetings,

you can override the override func draw(at point: CGPoint, in context: CGContext) from NSTextLayoutFragment and iterate over the text line fragments to customize it:

override func draw(at point: CGPoint, in context: CGContext) {
  for lineFragment in textLineFragments {
    lineFragment.draw(at: lineFragment.typographicBounds.origin, in: context)
  }
}

Source / Example: krzyzanowskim/STTextView