SwiftUI 4: представление назначения navigationDestination() не обновляется при изменении состояния
Во время экспериментов с новым
struct ContentView: View {
@State var data: [Int: String] = [
1: "One",
2: "Two",
3: "Three",
4: "Four"
]
var body: some View {
NavigationStack {
List {
ForEach(Array(data.keys).sorted(), id: \.self) { key in
NavigationLink("\(key)", value: key)
}
}
.navigationDestination(for: Int.self) { key in
if let value = data[key] {
VStack {
Text("This is \(value)").padding()
Button("Modify It") {
data[key] = "X"
}
}
}
}
}
}
}
Действия по воспроизведению проблемы:
Запустите код и нажмите на первый элемент в списке. Это приведет вас к подробному представлению об этом элементе.
Подробный вид показывает стоимость элемента. Он также имеет кнопку для изменения значения. Нажмите на эту кнопку. Вы заметите, что значение в подробном представлении не меняется.
Я отладил проблему, установив точки останова в другом месте. Мои наблюдения:
Когда я нажал кнопку, код в
быть казненным. Это как и ожидалось. Но переданное замыкание не выполняется, что объясняет, почему подробное представление не обновляется.
Кто-нибудь знает, это ошибка или ожидаемое поведение? Если это не ошибка, как я могу запрограммировать обновление значения в подробном представлении?
Кстати, если я вернусь к корневому представлению и нажму на первый элемент, чтобы снова перейти к его подробному представлению, закрытие перейдет к
1 ответ
The button
правильно меняет значение. По умолчаниюnavigationDestination
не создаетBinding
отношение между родителем и дочерним элементом, создающим переданные значенияimmutable
.
Поэтому вам следует создать отдельныйstruct
ребенку для достиженияBindable
поведение:
struct ContentView: View {
@State var data: [Int: String] = [
1: "One",
2: "Two",
3: "Three",
4: "Four"
]
var body: some View {
NavigationStack {
List {
ForEach(Array(data.keys).sorted(), id: \.self) { key in
NavigationLink("\(key)", value: key)
}
}
.navigationDestination(for: Int.self) { key in
SubContentView(key: key, data: $data)
}
}
}
}
struct SubContentView: View {
let key: Int
@Binding var data: [Int: String]
var body: some View {
if let value = data[key] {
VStack {
Text("This is \(value)").padding()
Button("Modify It") {
data[key] = "X"
}
}
}
}
}