У меня есть три кнопки, каждая кнопка соответствует значению в массиве данных. Когда пользователь нажимает кнопку, соответствующее значение будет отображаться в окне листа. Вот мой код:
struct TestView: View {
@State var data: [Int] = [100, 200, 300]
@State var presented: Bool = false
@State var index4edit: Int = 1
var body: some View {
HStack{
ForEach(1..<4){ index in
Button(action: {
index4edit = index
presented.toggle()
}){ Text(String(index)) }
.frame(width: 30, height: 30)
.padding()
}
}
.sheet(isPresented: $presented, content: {
Text("\(index4edit): \(data[index4edit-1])")
})
}
}
Моя проблема в том, что при первом нажатии кнопки, независимо от того, какая кнопка, всегда отображаются первые данные 100
. Причина в том, что данные index4edit
не обновились по первому клику, так всегда 1
, но почему? Спасибо.
Вы должны настроить index4edit
как реальный индекс (отсчитываемый от 0), а не индекс + 1. Вы также должны использовать data.indices
в ForEach
вместо ручного ввода диапазона.
struct TestView: View {
@State private var data: [Int] = [100, 200, 300]
@State private var presented: Bool = false
@State private var index4edit: Int = 0
var body: some View {
HStack {
ForEach(data.indices) { index in
Button(action: {
index4edit = index
presented.toggle()
}){ Text(String(index)) }
.frame(width: 30, height: 30)
.padding()
}
}
.sheet(isPresented: $presented, content: {
Text("\(index4edit): \(data[index4edit])")
})
}
}
struct TestView_Previews: PreviewProvider {
static var previews: some View {
TestView()
}
}
Это связано с тем, что представление листа создается при инициализации представления. Когда вы измените свое состояние, ваше представление не будет воссоздано, потому что ваша переменная состояния не используется в вашем представлении.
Чтобы решить эту проблему, просто используйте переменную State где-нибудь в коде, как в этом фиктивном примере.
HStack{
ForEach(1..<4){ index in
Button(action: {
index4edit = index
presented.toggle()
}){ Text(String(index) + (index4edit == 0 ? "" : "")) } //<<here is the State used
.frame(width: 30, height: 30)
.padding()
}
}
Теперь ваш вид будет перерисовываться при изменении состояния, поэтому ваш вид листа будет перерисован.