TechnologiesSwiftUI

OnInsertTableRowModifier struct

iOSmacOStvOSwatchOSvisionOS✓ renders

A table row modifier that adds the ability to insert data in some base

How it works

OnInsertTableRowModifier is the table-row modifier SwiftUI produces when you register an insertion handler on the rows of a Table. It bundles together the uniform type identifiers a row will accept on drop and the closure that turns a dropped payload into newly inserted rows, so the table itself manages where the drop lands and at which index your data should grow. Reach for it through the onInsert(of:perform:) modifier when you build a Table and want users to add rows by dragging external content into the row area, without writing your own drop-destination or index-math logic.

  1. Start from a Table bound to your data

    OnInsertTableRowModifier attaches to a Table's rows, so the table needs a mutable source of truth to insert into. Here Table(people) drives its rows from the @State private var people array, and each TableColumn("Name", value: \.name) / TableColumn("Role", value: \.role) describes a column; the modifier you add will mutate that same people array when a drop occurs.

  2. Declare the accepted types with onInsert(of:perform:)

    Calling .onInsert(of:perform:) on the table's rows is what creates the OnInsertTableRowModifier. The of: argument lists the uniform type identifiers the rows will accept, so the table only highlights as a drop target for payloads it can decode (for example a UTType.plainText or .url) and ignores everything else.

  3. Insert rows in the perform closure

    The perform: closure receives the destination index and the dropped item providers, and is your chance to splice new elements into the model. Inside it you would load each provider and call something like people.insert(newPerson, at: index), so the modifier hands you exactly where the user dropped and lets you grow the people array at that spot.

  4. Let the modifier compose with the row content

    OnInsertTableRowModifier conforms to TableRowModifier and returns a modified row collection, so it slots into the table's row builder the way a view modifier slots onto a view. Because applying it simply yields modified rows, the surrounding .padding() and the Table's own layout are untouched—only the rows gain the ability to receive inserts.

Try it — Add .onInsert(of: [.plainText]) { index, providers in people.insert(Person(name: "New", role: ""), at: index) } after the Table's closure and drag a piece of text onto a row to watch a fresh row appear at exactly the drop position.

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.

OnInsertTableRowModifier.swift
struct OnInsertTableRowModifierDemo: View {
    struct Person: Identifiable {
        let id = UUID()
        let name: String
        let role: String
    }

    @State private var people = [
        Person(name: "Alex", role: "Designer"),
        Person(name: "Sam", role: "Engineer"),
        Person(name: "Jamie", role: "PM")
    ]

    var body: some View {
        Table(people) {
            TableColumn("Name", value: \.name)
            TableColumn("Role", value: \.role)
        }
        .padding()
    }
}
Live preview
Name Role Alex Designer Sam Engineer Jamie PM
Name Role Alex Designer Sam Engineer Jamie PM
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →