---
title: Managing viewport layout and attachment reuse in text views
framework: uikit
role: article
role_heading: Article
path: uikit/managing-viewport-layout-and-attachment-reuse-in-a-text-view-subclass
---

# Managing viewport layout and attachment reuse in text views

Customize layout and preserve attachment views in your text view subclass.

## Overview

Overview If you build a text editor with rich attachments — like images, videos, or interactive controls — you may notice that attachment views flicker or lose their state when someone scrolls the attachment out of the viewport, or types in the same paragraph. This is because text views discard and recreate attachment views as part of their normal layout process. UITextView and NSTextView conform to NSTextViewportLayoutControllerDelegate, giving your subclass direct access to the layout process. You can override the delegate methods to respond to layout events and customize how text fragments appear. You can also register reuse policies to tell the text view which attachment views to preserve across scrolling and editing, eliminating flicker and preserving states like focus and playback position. Override viewport layout methods layoutViewport() encompasses the viewport layout process. Each time the visual state within the viewport changes, TextKit calls it. During each viewport layout process, NSTextViewportLayoutController calls the text view’s delegate methods at three points — before it starts, before each text layout fragment is about to be rendered, and after it completes. Override any of these methods in your UITextView (or NSTextView in macOS) subclass to customize what happens at each stage: class CustomTextView: UITextView {

override func textViewportLayoutControllerWillLayout(         _ textViewportLayoutController: NSTextViewportLayoutController     ) {         super.textViewportLayoutControllerWillLayout(textViewportLayoutController)         // Prepare any state before the layout pass begins.     }

override func textViewportLayoutController(         _ textViewportLayoutController: NSTextViewportLayoutController,         configureRenderingSurfaceFor textLayoutFragment: NSTextLayoutFragment     ) {         super.textViewportLayoutController(textViewportLayoutController, configureRenderingSurfaceFor: textLayoutFragment)         // Inspect or customize each laid-out text fragment.     }

override func textViewportLayoutControllerDidLayout(         _ textViewportLayoutController: NSTextViewportLayoutController     ) {         super.textViewportLayoutControllerDidLayout(textViewportLayoutController)         // Finalize layout after all fragments are positioned.     } } important: All overrides of viewport layout delegate methods must call super, because omitting it breaks layout. Query any NSTextViewportLayoutController state only inside textViewportLayoutControllerDidLayout(_:); querying it from other delegate methods can cause crashes. The following table shows the set of available override points:  |   |   |   |   |   |  Register reuse policies Use the registration API to preserve attachment views across layout passes. Call register(_:forTextAttachmentViewProviderType:) once during setup to declare the reuse behavior per provider type: // Retain video attachment views across both scrolling and paragraph edits. textView.register(     [.onScrollingOutOfViewport, .onEditingInlineParagraphs],     forTextAttachmentViewProviderType: VideoAttachmentViewProvider.self )

// Retain drawing views only when they scroll out of view. textView.register(     [.onScrollingOutOfViewport],     forTextAttachmentViewProviderType: DrawingAttachmentViewProvider.self ) After you register a provider type, the text view holds on to those attachment views when scrolling moves them out of view or editing changes the surrounding paragraph, and restores them when they come back. This automatically keeps video playback position and focused controls intact across scrolling and paragraph edits.

## See Also

### Layout

- [Using TextKit 2 to interact with text](uikit/using-textkit-2-to-interact-with-text.md)
- [Display text with a custom layout](uikit/display-text-with-a-custom-layout.md)
- [NSTextLayoutManager](uikit/nstextlayoutmanager.md)
- [NSTextContainer](uikit/nstextcontainer.md)
- [NSTextLayoutFragment](uikit/nstextlayoutfragment.md)
- [NSTextLineFragment](uikit/nstextlinefragment.md)
- [NSTextViewportLayoutController](uikit/nstextviewportlayoutcontroller.md)
- [NSTextViewportRenderingSurface](uikit/nstextviewportrenderingsurface.md)
- [NSTextViewportRenderingSurfaceKey](uikit/nstextviewportrenderingsurfacekey.md)
- [NSTextLayoutOrientationProvider](uikit/nstextlayoutorientationprovider.md)
