0

I'm building a macOS app with a sidebar which has elements that the user can rearrange. I'm using .onMove() to detect when the user moves an elements and a function to move the item. Here is my code for that:

NavigationView {
    List() {
        ForEach(instances) { instance in
            NavigationLink(destination: InstanceView(instance: instance), tag: instance, selection: $selectedInstance) {
                InstanceRow(instance: instance).id(UUID())
            }
        }
        .onMove(perform: move)
    }
    .listStyle(SidebarListStyle())
    .navigationTitle("Instances")
    .frame(minWidth: 150)
    .toolbar {
        ToolbarItem {
            Button(action: toggleSidebar, label: {
                Image(systemName: "sidebar.left")
            })
        }
    }
    .onAppear {
        selectedInstance = instances[0]
    }
}

And the move() function:

private func move(from source: IndexSet, to destination: Int) {
    let previousSelectedInstanceIndex: Int = instances.firstIndex(of: selectedInstance!)!
    var revisedItems: [Instance] = instances.map{$0}
        
    revisedItems.move(fromOffsets: source, toOffset: destination )
        
    for reverseIndex in stride(from: revisedItems.count - 1, through: 0, by: -1) {
        revisedItems[reverseIndex].userOrder = Int16(reverseIndex)
    }
        
    do {
        try viewContext.save()
    } catch {
        // Error handling isn't finished yet
        let nsError = error as NSError
        fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
    }
    
    selectedInstance = instances[previousSelectedInstanceIndex]

}

Currently when I drag an item in the list, it shows a blue line where the item will end up when the user lets go. I was wondering how I could change this to act similar to how finder allows you to move items in the sidebar, where the other items animate around it when you drag it over them. I'm using swiftUI.

Thanks!

Cameron Delong
  • 454
  • 1
  • 6
  • 12
  • Not sure if this is the answer you're looking for, but have you tried the `.move(fromOffsets:, toOffset:)` method that belongs to collections (arrays)? In your `private func move(...)`, consider using `instances.move(fromOffsets: source, toOffset: destination)`. SwiftUI should natively move these items for you after the move's completion. – Ben Myers Jun 24 '21 at 19:55
  • 1
    Thanks for the response. I already have the functionality for moving instances around, I just don't like the way it looks/animates, and I was trying to figure out how to change that, so I don't think that's quite what I need. Thanks though! – Cameron Delong Jun 25 '21 at 01:18
  • Ah yeah, happy to make suggestions. I've been struggling to grasp the nature of SwiftUI's `move(...)` method myself. I'll keep an eye on this question for further developments! – Ben Myers Jun 25 '21 at 07:09

0 Answers0