SwiftUI `OutlineGroup` Should Support Native Reordering with `reorderable` / `reorderContainer`

Description

I would like to request native reordering support for SwiftUI hierarchical views, especially OutlineGroup and List(_:children:).

In iOS 27, SwiftUI introduces the new reordering APIs:

.reorderable()
.reorderable(collectionID:)
.reorderContainer(for:move:)
.reorderContainer(for:in:move:)

These APIs work well for flat collections and explicit sectioned collections, but they do not appear to integrate with OutlineGroup, even though OutlineGroup is the natural SwiftUI API for tree-structured data.

Currently, OutlineGroup hides the internal recursive ForEach / DisclosureGroup structure, so there is no obvious place to apply reorderable(collectionID:) at each hierarchy level.

Current Working Pattern for Sections

This works when each parent is represented manually as a section:

struct SectionModel: Identifiable {
    let id: UUID
    var title: String
    var items: [Item]
}

struct Item: Identifiable {
    let id: UUID
    var title: String
}

struct ContentView: View {
    @State private var sections: [SectionModel] = sampleSections

    var body: some View {
        List {
            ForEach(sections) { section in
                Section(section.title) {
                    ForEach(section.items) { item in
                        Text(item.title)
                    }
                    .reorderable(collectionID: section.id)
                }
            }
        }
        .reorderContainer(for: Item.self, in: SectionModel.ID.self) { difference in
            apply(difference)
        }
    }

    private func apply(_ difference: ReorderDifference<Item.ID, SectionModel.ID>) {
        // Move item between explicit sections.
    }
}

But this does not scale naturally to arbitrary tree data.

Desired API

Ideally, this should work with OutlineGroup:

struct Node: Identifiable {
    let id: UUID
    var title: String
    var children: [Node]?
}

struct ContentView: View {
    @State private var nodes: [Node] = sampleTree

    var body: some View {
        List {
            OutlineGroup(nodes, children: \.children) { node in
                Text(node.title)
            }
            .reorderable()
        }
        .reorderContainer(for: Node.self) { difference in
            apply(difference)
        }
    }

    private func apply(_ difference: ReorderDifference<Node.ID, ???>) {
        // Move node within the tree.
    }
}

For hierarchical data, SwiftUI would need to expose the parent or collection identity of the source and destination. For example, something like:

.reorderableTree(
    children: \.children,
    allowsMoveIntoChildren: true
)

Or an overload such as:

OutlineGroup(nodes, children: \.children) { node in
    Text(node.title)
}
.reorderable(collectionID: \.parentID)

With a ReorderDifference that includes:

sourceParentID
destinationParentID
destinationPosition
movedItemIDs

Why This Matters

Many apps represent user-created hierarchical data:

  • folders
  • bookmark collections
  • nested lists
  • project outlines
  • document trees
  • sidebar hierarchies

OutlineGroup is the natural SwiftUI abstraction for displaying this data, but reordering currently requires either:

  1. 1abandoning OutlineGroup and rebuilding a recursive outline manually;
  2. 2flattening the hierarchy into sections, losing the real outline interaction;
  3. 3using older manual drag/drop APIs;
  4. 4falling back to UIKit/AppKit.

None of these approaches feels aligned with SwiftUI's declarative model.

Specific Request

Please consider adding native reorder support to OutlineGroup and List(_:children:), including support for:

  • moving items within the same parent;
  • moving items between parents;
  • optionally moving an item into another item as a child;
  • preventing invalid moves, such as moving a parent into one of its descendants;
  • exposing source and destination parent identifiers in the move callback;
  • preserving SwiftUI's built-in disclosure UI.

Minimal Example of the Current Limitation

This is the kind of code I would expect to be possible:

List {
    OutlineGroup(nodes, children: \.children) { node in
        Text(node.title)
    }
    .reorderable()
}
.reorderContainer(for: Node.self, in: Node.ID.self) { difference in
    moveNode(using: difference)
}

But because OutlineGroup creates its recursive rows internally, there is no clear way to attach reorderable(collectionID:) to each parent's child collection.

Expected Outcome

SwiftUI should provide a first-class way to reorder hierarchical data displayed with OutlineGroup, similar to how flat and sectioned collections can now use reorderable and reorderContainer.

FB23319159

SwiftUI &#96;OutlineGroup&#96; Should Support Native Reordering with &#96;reorderable&#96; / &#96;reorderContainer&#96;
 
 
Q