Text system improvements

For developing an iOS fully-featured code editor (i.e line numbers + color pass for syntax highlighting + collapsible sections + debug markers/highlights) what would be the best strategy for iOS 27?

  1. UITextView with new viewport control delegate
  2. Custom TextKit2 UIView
  3. Custom TextKit1 UIView (this was the recommendation I got as of WWDC25)
Answered by Frameworks Engineer in 892224022

Hi!

Option 1 is definitely the best way to go. You can use the viewport controller delegate's configureRenderingSurfaceForTextLayoutFragment: method to add line numbers, and collapsible sections.

You'll have to use your own parser to add syntax highlighting, and then apply this as attributes to the NSTextStorage. You could use the NSTextContentStorage delegate methods as well.

If you have more specific questions, feel free to ask another question or post a feedback.

  • Tarun

For a new code editor on iOS 27, go with UITextView backed by TextKit 2 + the new viewport control delegate — not custom TextKit 1.

The WWDC25 push toward TextKit 1 was because TextKit 2's viewport management wasn't flexible enough for gutter sync and precise line positioning. iOS 27's viewport control delegate fixes exactly that.

Quick mapping:

  • Line numbers/markers: use the viewport delegate to track visible line fragments, position a synced gutter view. NSTextLayoutFragment gives per-line geometry.
  • Syntax highlighting: apply attributes via text storage, highlight incrementally on the visible range the delegate surfaces — not the whole document.
  • Collapsible sections: TextKit 2's content storage lets you control which ranges lay out, instead of TextKit 1's manual range math.

One caveat: confirm the specific delegate hooks meet your gutter-sync needs before committing — that's the part that historically forced people back to TextKit 1.

— Divya Ravi, Senior iOS Engineer

Hi!

Option 1 is definitely the best way to go. You can use the viewport controller delegate's configureRenderingSurfaceForTextLayoutFragment: method to add line numbers, and collapsible sections.

You'll have to use your own parser to add syntax highlighting, and then apply this as attributes to the NSTextStorage. You could use the NSTextContentStorage delegate methods as well.

If you have more specific questions, feel free to ask another question or post a feedback.

  • Tarun

Thanks Tarun, and for a great and clear presentation video!

Regarding line numbering, I've seen the sample code from this year. If I wanted to animate the toggle, something like

UIView.animate {
    textViewportLayoutController.layoutViewport()
}

after textViewportLayoutControllerReceivedSetNeedsLayout() seems reasonable?

Currently paragraphs are flying around if I try it but I'm guessing that's some caching/index reuse?


And regarding NSTextStorage, would it be possible to hold some kind of double-booking wherein I get a fast layout pass of the actual text as single run, and only adjust the color attributes for the viewport? (assuming I already keep the tokenized metadata separately for each run)

Thanks!

We discourage using textViewportLayoutController.layoutViewport() directly. textViewportLayoutControllerReceivedSetNeedsLayout() essentially does the same thing.

Did you mean toggling the collapsible sections? Toggling line number gutter is outside of the textView, so you don't need to layoutViewport at all.

If you're trying to toggle collapsible sections, and animate them, you'll have to do something similar to the work done in this sample code: https://developer.apple.com/documentation/UIKit/using-textkit-2-to-interact-with-text.

The other, more complicated way is to take a snapshot at WillLayout, and DidLayout and then animate between the two states.

Text system improvements
 
 
Q