NSTextLayoutManager giving incorrect fragment frame

I have an NSTextLayoutManager set up with NSTextContentStorage and NSTextContainer. To work out the height of the content, I call the method updateContentSizeIfNeeded() which contains the code

textLayoutManager.enumerateTextLayoutFragments(from: textLayoutManager.documentRange.endLocation, options: [.reverse, .ensuresLayout]) { layoutFragment in
    height = layoutFragment.layoutFragmentFrame.maxY
    return false
}

The first time this is called, it returns the correct height. Then I add a new character to the start of the NSTextContentStorage like so

textContentStorage.performEditingTransaction {
    storage.replaceCharacters(in: NSRange(location:0, length: 1), with: "a")
}

textLayoutManager.ensureLayout(for: textLayoutManager.documentRange)
textLayoutManager.textViewportLayoutController.layoutViewport()
updateContentSizeIfNeeded()

This time, the height returned is ~600px too big. The state of the NSTextLayoutFragment is set to layoutAvailable

The next time I add a character to textContentStorage using the same code above, the height returned is correct again.

I can work around this by calling enumerateTextLayoutFragments from the start of the document and not in reverse, then ignoring all fragments except the last one, but I don't know if that's the correct way to do it, or if I should be doing something else

Thinking that maybe I should be observing to NSTextLayoutManager.usageBoundsForTextContainer for changes through KVO, but it never seems to change so maybe not?

This sounds like a bug that TextKit2 doesn't update the layout fragment frames correctly. Would you mind to file a feedback report with your testing project, and share the report ID here?

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

NSTextLayoutManager giving incorrect fragment frame
 
 
Q