'List with drag and drop to reorder on SwiftUI

How can I add drag and drop to reorder rows on SwiftUI? Just a clean solution without 'Edit mode'. Here an example:

enter image description here

UPDATE

I asked this question on The SwiftUI Lab and the author replied with this code. Only works on iPad

    import SwiftUI

    struct Fruit: Identifiable {
        let id = UUID()
        let name: String
        let image: String
    }
            struct ContentView: View {
            @State var selection: Set<UUID> = []

            @State private var fruits = [
                Fruit(name: "Apple", image: "apple"),
                Fruit(name: "Banana", image: "banana"),
                Fruit(name: "Grapes", image: "grapes"),
                Fruit(name: "Peach", image: "peach"),
                Fruit(name: "Kiwi", image: "kiwi"),
            ]

            var body: some View {

                VStack {
                    NavigationView {
                        List(selection: $selection) {
                            ForEach(fruits) { fruit in
                                HStack {
                                    Image(fruit.image)
                                        .resizable()
                                        .frame(width: 30, height: 30)

                                    Text(fruit.name)
                                }
                            }
                            .onMove { _, _ in }
                        }
                        .navigationBarTitle("Fruits (Top)")
                    }
                }
            }
        }


Solution 1:[1]

To put the list in the edit mode when the user long presses an item, you can use a state flag and set the edit environment value accordingly. It is important to make the flag changes animated in order not to look very weird.

struct ContentView: View {
    @State private var fruits = ["Apple", "Banana", "Mango"]
    @State private var isEditable = false

    var body: some View {
        List {
            ForEach(fruits, id: \.self) { user in
                Text(user)
            }
            .onMove(perform: move)
            .onLongPressGesture {
                withAnimation {
                    self.isEditable = true
                }
            }
        }
        .environment(\.editMode, isEditable ? .constant(.active) : .constant(.inactive))
    }

    func move(from source: IndexSet, to destination: Int) {
        fruits.move(fromOffsets: source, toOffset: destination)
        withAnimation {
            isEditable = false
        }
    }
}

Solution 2:[2]

Draggable items in SwiftUI List with changing the order

I solved it with return NSItemProvider() when I try to drag an item. And standard .onMove function.

If I understand correctly, I am grabbing a row container as an NSObject (thanks to initialization NSItemProvider), and .OnMove allows me the ability to reorder items in the List.

I'm still learning and may misunderstand some of the nuances. There must be a better explanation. But it definitely works (I only tested this on ios 15 because I use the .background property in my project).

// View
List {
    ForEach(tasks) { task in
        HStack { // Container of a row
             NavigationLink {
                 Text("There will be an editing View")
             } label: {
                 TaskListRowView(task: task)
             }
        }
        .onDrag { // mean drag a row container
             return NSItemProvider()
        }
     }
     .onDelete(perform: deleteItems)
     .onMove(perform: move) 
}

// Function
func move(from source: IndexSet, to destination: Int) {
    tasks.move(fromOffsets: source, toOffset: destination )
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 codingFriend1
Solution 2 Roman Predein