TechnologiesSwiftUISearch and Find

RenameAction struct

iOSmacOStvOSwatchOSvisionOSiOS 16.0+✓ renders

An action that activates a standard rename interaction.

How it works

RenameAction is a structure that triggers the rename interaction for the item a view represents, letting the system route a standard rename gesture to your own editing logic. SwiftUI supplies it through the environment so that platform affordances — a context-menu Rename command, a keyboard shortcut, or a long-press — can all begin renaming through one consistent entry point. Reach for it when a view stands in for a named, user-editable item, such as a document, folder, or list row, and you want a single place to start the rename rather than wiring up each trigger by hand. Calling the action is what hands control to the closure you registered, where you typically reveal an editable field and move focus into it.

  1. Register the handler with renameAction(_:)

    The renameAction modifier attaches a closure that defines what renaming means for this view and publishes a RenameAction into the environment for descendants to invoke. Here it sets isRenaming = true and focused = true, the two pieces of state that swap the label for an editable field and put the cursor in it.

  2. Drive the edit surface from observable state

    Because the action only flips state, the view's appearance is data-driven: @State private var isRenaming chooses between a read-only Text(name) and an editable TextField("Name", text: $name), while @State private var name holds the value being renamed. The action does not touch the UI directly — it changes state, and the body reacts.

  3. Hand focus to the field with FocusState

    A rename should leave the user typing immediately, so the handler also writes to a @FocusState private var focused bound through .focused($focused) on the TextField. Setting focused = true inside the closure activates the field the moment the rename begins.

  4. Commit the rename and dismiss

    The same state that started the edit ends it: .onSubmit { isRenaming = false } returns the view to its label form when the user confirms, so the rename interaction has a clear completion. The new value already lives in name via the $name binding.

  5. Invoke from system rename triggers

    Once registered, the action backs the standard rename affordances. The .contextMenu here exposes a Button("Rename") that runs the identical isRenaming = true; focused = true logic, mirroring what renameAction itself begins — so menu, gesture, and shortcut all start renaming the same way.

Try it — Remove the focused = true line from the closure passed to .renameAction and trigger a rename: the TextField appears but the cursor no longer lands in it, showing exactly what the action's focus side effect contributes.

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.

RenameAction.swift
struct RenameActionDemo: View {
    @State private var name = "Untitled Folder"
    @State private var isRenaming = false
    @FocusState private var focused: Bool

    var body: some View {
        VStack(spacing: 16) {
            if isRenaming {
                TextField("Name", text: $name)
                    .textFieldStyle(.roundedBorder)
                    .focused($focused)
                    .onSubmit { isRenaming = false }
            } else {
                Text(name)
                    .font(.headline)
            }
            Text("Long-press the label to rename")
                .font(.caption)
                .foregroundStyle(.secondary)
        }
        .padding()
        .contextMenu {
            Button("Rename") {
                isRenaming = true
                focused = true
            }
        }
        .renameAction { isRenaming = true; focused = true }
    }
}
Live preview
Untitled Folder Long-press the label to rename
Untitled Folder Long-press the label to rename
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →