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.
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 peoplearray, and eachTableColumn("Name", value: \.name)/TableColumn("Role", value: \.role)describes a column; the modifier you add will mutate that samepeoplearray when a drop occurs.Declare the accepted types with onInsert(of:perform:)
Calling
.onInsert(of:perform:)on the table's rows is what creates the OnInsertTableRowModifier. Theof: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 aUTType.plainTextor.url) and ignores everything else.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 likepeople.insert(newPerson, at: index), so the modifier hands you exactly where the user dropped and lets you grow thepeoplearray at that spot.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.
.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.
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()
}
}