skip to Main Content

Currently, I create a generic list as follows:

List {
    ForEach(viewModel.categoryItems) { category in
        Text("(category.category)")
    }.onMove { indexSet, newOffset in
        viewModel.categoryItems.move(fromOffsets: indexSet, toOffset: newOffset)
    }
}.toolbar {
    ToolbarItem {
        if viewModel.categoryItems.count > 0 {
            EditButton()
        }
    }
}

I would like to be able to number this list and also have those numbers change on move (2 becomes 1 if moved into the 1 place).

2

Answers


  1. one option would be to use the indices property of the array. Something like this:

    struct ContentView: View {
        @ObservedObject
        var viewModel = Model()
    
        var body: some View {
            List {
                ForEach(viewModel.categoryItems.indices, id: .self) { idx in
                    Text("(idx) - (viewModel.categoryItems[idx].category)")
                }.onMove { indexSet, newOffset in
                    viewModel.categoryItems.move(fromOffsets: indexSet, toOffset: newOffset)
                }
            }
        }
    }
    
    

    Downside is that you have to access the object via the array as you only get the current index within the loop.

    Some more elaborate solutions are listed here: How to get row index in SwiftUI List?

    Login or Signup to reply.
  2. Give your Category Item a nr property. Then in .onMove after the move itself just renumber, e.g. like this:

    struct Category: Identifiable {
        let id = UUID()
        var nr: Int
        var category: String
    }
    
    struct ContentView: View {
        
        @State private var categoryItems = [
            Category(nr: 1, category: "alpha"),
            Category(nr: 2, category: "bravo"),
            Category(nr: 3, category: "charly"),
            Category(nr: 4, category: "delta"),
            Category(nr: 5, category: "echo")
        ]
        
        var body: some View {
            NavigationView {
                List {
                    ForEach(categoryItems) { category in
                        Text("(category.nr) - (category.category)")
                    }.onMove { indexSet, newOffset in
                        categoryItems.move(fromOffsets: indexSet, toOffset: newOffset)
                        // renumber
                        for i in 0..<categoryItems.count {
                            categoryItems[i].nr = i+1
                        }
                        
                    }
                }.toolbar {
                    ToolbarItem {
                        if categoryItems.count > 0 {
                            EditButton()
                        }
                    }
                }
            }
        }
    }
    

    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search