Я подозреваю, что это происходит, потому что все в вашем TestView перерисовывается, в то время как переменная state изменяется. Таким образом, ваше предупреждение отображается только для первой итерации цикла. Решение состоит в том, чтобы изменить другую переменную, которая должна содержать индекс нажатой кнопки:
struct TextView: View {
@State var showAlert = false
@State var clickedButtonIndex = 0
var body: some View {
VStack {
ForEach(0...5, id: \.self) { n in
Button(action: {
self.showAlert.toggle()
self.clickedButtonIndex = n
}) {
Text("Button \(n)")
}
.padding(20)
.border(Color.green, width: 4)
.padding(8)
.alert(isPresented: self.$showAlert) {
Alert(title: Text("Button \(self.clickedButtonIndex) clicked"))
}
}
}
}
}
И вы получите такой результат: 