swiftswiftui

Get index in ForEach in SwiftUI


I have an array and I want to iterate through it initialize views based on array value, and want to perform action based on array item index

When I iterate through objects

ForEach(array, id: \.self) { item in
  CustomView(item: item)
    .tapAction {
      self.doSomething(index) // Can't get index, so this won't work
    }
}

So, I've tried another approach

ForEach((0..<array.count)) { index in
  CustomView(item: array[index])
    .tapAction {
      self.doSomething(index)
    }
}

But the issue with second approach is, that when I change array, for example, if doSomething does following

self.array = [1,2,3]

views in ForEach do not change, even if values are changed. I believe, that happens because array.count haven't changed.

Is there a solution for this?


Solution

  • This works for me:

    Using Range and Count

    struct ContentView: View {
        @State private var array = [1, 1, 2]
    
        func doSomething(index: Int) {
            self.array = [1, 2, 3]
        }
        
        var body: some View {
            ForEach(0..<array.count) { i in
              Text("\(self.array[i])")
                .onTapGesture { self.doSomething(index: i) }
            }
        }
    }
    

    Using Array's Indices

    The indices property is a range of numbers.

    struct ContentView: View {
        @State private var array = [1, 1, 2]
    
        func doSomething(index: Int) {
            self.array = [1, 2, 3]
        }
        
        var body: some View {
            ForEach(array.indices) { i in
              Text("\(self.array[i])")
                .onTapGesture { self.doSomething(index: i) }
            }
        }
    }