APIs that shipped in the 27.0 SDK but had no Axiom coverage, each checked against the RC SDK and the published snippets compiled. - AVFoundation: async session activation and the deactivation and resumption notifications that replace interruption types; throwing AVAudioEngine and node APIs (connectNode, playAudio, installAudioTap) that replace calls that trapped on misuse; realtime-safe render blocks are ObjC-only. - PhotoKit: Apple Reference Image viewer, the persistent change history observer, asset keyword/rating/caption editing, the root folder collection, synced-only identifier mapping, and background resource upload configuration. - ScreenCaptureKit: clip buffering, the recording editor, new error codes, and a per-platform availability table now that it ships beyond macOS. The Presenter Overlay delegate methods use their shipped names (outputVideoEffectDidStart/Stop), and the iOS screen-capture sample compiles under Swift 6. - macOS 27 denies another team's app or app group container without a prompt; the sandbox skill explains the failure and the fixes. - Background Assets: the languageChange content request (a build break for exhaustive switches), localized file reads, and async exclusive control that must be used on both the app and extension side. - XCUITest drives VoiceOver and asserts spoken output (XCUIDevice.shared.voiceOverService). - TextKit: per-edge block borders, hit-testing transformed text, and UITextChecker grammar checking. - Xcode 27 silently ignores -ld_classic and rejects -ld64; Clang module names must be unique per dependency scan. - Media router rows for 27 camera controls and iPhone Duo camera direction.
6.6 KiB
name, description
| name | description |
|---|---|
| textkit-ref | Reference — Complete TextKit 2 guide covering architecture, migration from TextKit 1, Writing Tools integration, and SwiftUI TextEditor with AttributedString through iOS 27 |
TextKit 2 Reference
This reference helps you work with Apple's TextKit 2 framework for custom text rendering, rich text editing, and Writing Tools integration. It covers architecture, migration from TextKit 1, and iOS 26–27 features.
When to Use This Reference
Use this reference when you're:
- Building custom text views or rich text editors
- Migrating from TextKit 1 to TextKit 2
- Integrating Writing Tools (iOS 18+)
- Working with SwiftUI TextEditor and AttributedString (iOS 26+)
- Debugging text layout issues or unexpected fallbacks to TextKit 1
- Customizing rendering surfaces or attachment view recycling from inside a UITextView subclass (iOS 27+)
- Checking grammar programmatically with
UITextChecker, styling individual edges of a text block, or hit-testing text drawn through a transform (iOS 27+)
Not sure if you need TextKit 2? If you're using standard Text, TextField, or UILabel, you probably don't. TextKit 2 is for custom text rendering, syntax highlighting, or rich text editing beyond what built-in controls provide.
Example Prompts
Questions you can ask Claude that will draw from this reference:
- "How do I migrate my text view from TextKit 1 to TextKit 2?"
- "Why is my UITextView falling back to TextKit 1?"
- "How do I count lines in TextKit 2 without glyph APIs?"
- "How do I integrate Writing Tools with my custom text editor?"
- "How do I use AttributedString with SwiftUI TextEditor in iOS 26?"
- "What's the difference between NSTextRange and NSRange?"
- "How do I customize text fragment rendering inside a UITextView without losing input or accessibility?"
- "How do I recycle inline attachment views in my text editor?"
- "How do I run grammar checking on a string with
UITextChecker?" - "How do I put a border on only the bottom edge of an
NSTextBlockon iOS?" - "My custom text view draws rotated text — how do I make taps select the right characters?"
What's Covered
Core Architecture
- Three-layer MVC pattern (Model, Controller, View)
- NSTextContentManager, NSTextLayoutManager, NSTextViewportLayoutController
- Object-based ranges (NSTextLocation, NSTextRange) vs integer indices
Migration from TextKit 1
- Paradigm shift from glyphs to elements
- NSRange ↔ NSTextRange conversion patterns
- Fallback triggers to avoid (accessing
.layoutManagercauses one-way fallback) - Why glyph APIs are dangerous for international text
Writing Tools (iOS 18+)
- TextKit 2 requirement for full experience
- Lifecycle delegate methods
- Protected ranges for code blocks and quotes
- Writing Tools Coordinator for custom text engines (iOS 26+)
SwiftUI TextEditor (iOS 26+)
- AttributedString binding
- Custom formatting definitions
- Value constraints
- Selection handling
- AttributedString text alignment and line height control
- Programmatic selection replacement
- DiscontiguousAttributedSubstring for non-contiguous selections
Viewport Rendering Surfaces & Attachment Reuse (iOS 27)
NSTextViewportRenderingSurface– render text fragments from a custom view without building a full custom text engine- Subclassable viewport delegate on framework text views — override
NSTextViewportLayoutControllerDelegatehooks directly inside aUITextViewsubclass registerTextAttachmentViewProviderReusePolicy(_:forTextAttachmentViewProviderType:)– recycle inline attachment views instead of rebuilding them- Collapsible content via
shouldEnumerate— exclude collapsed paragraphs from layout using theNSTextContentStorageDelegate
Text Blocks, Hit Testing & Grammar Checking (iOS 27)
- Per-edge
NSTextBlockborders, padding, and margins –setBorderColor(_:rectEdge:),borderColor(for:),setWidth(_:type:for:rectEdge:),width(for:rectEdge:),widthValueType(for:rectEdge:) - Transformed-text hit testing –
NSTextSelectionDataSource.convertInteractionPoint(_:toContainerAt:) - Grammar checking –
UITextChecker.requestGrammarChecking(of:range:waitForAllResults:),ignoreGrammarRange(_:inSentence:), and the macOS-onlygrammarDetailskeys
Documentation Scope
This page documents the textkit-ref skill in the axiom-uikit suite — a comprehensive reference Claude uses when answering TextKit 2 questions. The skill contains detailed API documentation, code examples, and migration patterns.
For automated scanning: Use the textkit-auditor agent to scan your codebase for TextKit 1 fallback triggers and migration opportunities.
For typography and Dynamic Type: See typography-ref for font handling, text styles, and accessibility considerations.
Key Patterns
Checking for TextKit 2 (Critical)
Always check TextKit 2 first to avoid triggering fallback:
// ✅ GOOD: Check TextKit 2 first
if let textLayoutManager = textView.textLayoutManager {
// TextKit 2 code
} else if let layoutManager = textView.layoutManager {
// TextKit 1 fallback only for old OS
}
// ❌ BAD: Accessing .layoutManager triggers one-way fallback
if let layoutManager = textView.layoutManager {
// You're now stuck in TextKit 1!
}
Creating a TextKit 2 Text View
// iOS 16+ / macOS 13+
let textView = UITextView(usingTextLayoutManager: true)
Writing Tools Integration
// Lifecycle awareness
func textViewWritingToolsWillBegin(_ textView: UITextView) {
isSyncing = false // Pause syncing during Writing Tools
}
func textViewWritingToolsDidEnd(_ textView: UITextView) {
isSyncing = true // Resume syncing
}
Known Limitations
- One-way fallback – Accessing
.layoutManagerpermanently switches to TextKit 1 - No glyph APIs – Use NSTextLocation and layout fragments instead
- NSTextTable unsupported – Use NSTextList or custom layouts
Related Resources
- textkit-auditor – Autonomous agent that scans for TextKit 1 fallback triggers
- typography-ref – Typography, Dynamic Type, and font handling reference
- WWDC 2021-10061 – Meet TextKit 2
- WWDC 2024-10168 – Get started with Writing Tools
- WWDC 2025-280 – Cook up a rich text experience in SwiftUI
- WWDC 2026-370 – Viewport rendering surfaces and attachment reuse in TextKit 2