I using SwiftUI to wrap a NSTextView to support rich text editing. I created a subclass ImageAttachment and provided my own viewProvider and attachmentView. The insertion of the image works fine, but when I typing in the same paragraph of the image, the image will flicker during typing and pause. after typing it sometimes just display nothing, but after refresh or click other places, the image shows.
The interesting part is if I typing in other paragraph, the image attachment displays well.
I don't think the flicker should happen while typing in the same paragraph of the attachment, but not sure if there is a way to enforce the layout stable for the paragraph?
Thanks for posting. I built a minimal test to try to reproduce this — a SwiftUI NSViewRepresentable-wrapped NSTextView with a custom NSTextAttachment subclass and a viewProvider returning a custom NSView. I then stress-tested it against five plausible causes, and none of them reproduced any flicker:
- Baseline pattern — custom attachment + view provider returning a tinted layer-backed view, type in the same paragraph as the inserted attachment: stable.
- No caching in
loadView()— every call constructs a brand-newNSViewwith fresh subviews and constraints: stable. - Aggressive layout invalidation on every keystroke —
NSTextLayoutManager.invalidateLayout(for: documentRange)from atextDidChange:delegate: stable. - Mixed content sources — both
attachment.imageset to a programmatically drawnNSImageand a customviewProviderreturning a separateNSView: stable. - Raster image content —
loadView()returns anNSViewcontaining anNSImageViewwith a realNSBitmapImageRep-backedNSImageinstead of a layer-tinted plain view: stable.
That tells me the flicker isn't in any of the most common anti-patterns — it's something specific to your implementation that I haven't anticipated. To narrow it down, could you share the following?
-
Your
ImageAttachmentclass, including:- The
viewProvider(for:location:textContainer:)override - The
NSTextAttachmentViewProvider.loadView()implementation - Whatever you mean by "attachmentView" — is that a property you added to your subclass, or are you setting
attachment.image, or something else? The exact wiring matters here.
- The
-
Your
NSViewRepresentable(orNSTextView-wrapping code), especially:- Any
NSTextViewDelegatemethods you implement - Any
textStorageDidProcessEditing:/textDidChange:handlers - Any code that re-applies attributes after a text change (for example, syntax highlighting, autocomplete, or formatting updates)
- Whether you ever call
addSubviewon the attachment view yourself, rather than letting the framework manage its placement.
- Any
-
Whether you have a custom
NSTextStoragesubclass. If your storage'sprocessEditingreapplies attributes (including the attachment) on every edit, that could trigger the framework to requery the view. -
How your image loads. Is it always available synchronously by the time
loadView()runs, or is there an async fetch (network, disk, render queue) that makes the image briefly unavailable on each load? An async load on every paragraph relayout would look exactly like flicker. -
macOS version you're targeting and testing on. The TextKit 2 vs TextKit 1 default and several
NSTextAttachmentViewProviderbehaviors differ across releases — I tested on macOS 26.4 with TextKit 2. -
A small Xcode project that reproduces the behavior, if you can put one together. It doesn't need to be your full editor — even a single text view with one custom attachment subclass would let me see what's different from my repro. Given that five plausible causes don't reproduce in my project, having yours that does would let me pinpoint the difference quickly.
Your "different paragraph types fine, same paragraph flickers" observation strongly suggests paragraph-level relayout is the trigger — typing in the same paragraph forces that paragraph to re-layout, which is when the attachment view gets requeried. The remaining question is what specifically about your code makes that requery destructive instead of seamless.