TechnologiesSwiftUI

TextEditorStyle protocol

iOSmacOStvOSwatchOSvisionOS✓ renders

A specification for the appearance and interaction of a text editor.

How it works

TextEditorStyle is the protocol that defines the visual appearance and behavior of a TextEditor view. Rather than reaching for overlays, backgrounds, or border modifiers to dress up a multiline text field, you adopt one of the built-in styles to get a coherent, platform-appropriate look that tracks focus and the surrounding environment. Apply a style when you want a TextEditor to read as a distinct, bounded editing surface, and let the style handle the chrome for you.

  1. Apply a style with textEditorStyle(_:)

    The textEditorStyle(_:) modifier is the entry point: you attach it to a TextEditor and pass a value conforming to TextEditorStyle. In the example, .textEditorStyle(.roundedBorder) is applied directly to the TextEditor(text: $note), swapping the editor's default plain appearance for the bordered one without any other changes to the view.

  2. Choose a built-in style value

    TextEditorStyle vends static, type-erased values you reference with leading-dot syntax. .roundedBorder draws the editor inside a rounded, outlined container that visually separates it from adjacent content, while .plain (or .automatic) gives the unadorned editor. The example selects .roundedBorder so the note area reads as a framed field.

  3. Bind the editor to mutable text

    A style governs presentation only; the editor still needs a writable text binding to operate on. Here TextEditor(text: $note) binds to the @State private var note so typing flows back into state, and the chosen TextEditorStyle simply wraps that live editing surface.

  4. Let the style inherit through the environment

    Because textEditorStyle(_:) sets the style in the environment, it cascades to TextEditor views nested beneath where you call it, not just the one it's attached to. Applying it on the TextEditor inside the VStack styles that editor; lifting the modifier to an enclosing container would style every TextEditor in that subtree uniformly.

Try it — Change .textEditorStyle(.roundedBorder) to .textEditorStyle(.plain) to see the bordered container disappear and the editor blend flush into the VStack.

Example & preview

Press Run live & edit to compile it in your browser — then edit the Swift on the left and the preview re-renders live.

TextEditorStyle.swift
struct TextEditorStyleDemo: View {
    @State private var note = "Meeting notes\nDiscuss Q3 roadmap"
    var body: some View {
        VStack(alignment: .leading, spacing: 12) {
            Text("Notes")
                .font(.headline)
            TextEditor(text: $note)
                .textEditorStyle(.roundedBorder)
                .frame(height: 140)
        }
        .padding()
    }
}
Live preview
Notes Meeting notes\nDiscuss Q3 roadmap
Notes Meeting notes\nDiscuss Q3 roadmap
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →