我的设置:
我有一个 ContentView
表示最终selection
的长度(selection.count
)。因此,我需要使用 @State
propertyWrapper
在我的 ContentView
上使用 selection
变量,因为我想要 View
在值发生变化时立即获取更新。该选择应该在我的 SelectionView
上进行,因此我在 ContentView
上的 selection
变量之间创建一个 Binding
> 和 SelectionView
。
我的问题:当 selection
变量更改时,我的 SelectionView
上的 UI 也应该更新,但因为它使用 @Binding
而不是 @State
View 不会更新。因此,我需要一些可以同时使用 @State
和 @Binding
或 @Binding
的东西,这也使 UI 重新加载.
struct ContentView: View {
@State var selection: [Int] = []
var body: some View {
NavigationView {
Form {
NavigationLink(destination: SelectionView(selection: $selection)) {
Text("Selection: \(selection.count)")
}
}
}
}
}
struct SelectionView: View {
@Binding var selection: [Int]
var body: some View {
NavigationView {
Form {
ForEach((0...9).identified(by: \.self)) { i in
Button(action: {
if self.selection.contains(i) {
self.selection = self.selection.filter { !($0 == i) }
} else {
self.selection.append(i)
}
}) {
if self.selection.contains(i) {
Text("Unselect \(i)")
} else {
Text("Select \(i)")
}
}
}
}
}
}
}
注意:如果我在 SelectionView
上使用 @State
而不是 @Binding
,它可以正常工作(这显然要求我不要创建我想要的绑定(bind))。
最佳答案
您的绑定(bind)没有任何问题。这是正确的做法,而且它会按照您想要的方式发挥作用。绑定(bind)是您在 SwiftUI 中传递可变状态的方式,您正在这样做,并且它有效。对绑定(bind)的更改确实会使 View 重新加载。
为了让自己相信这一点,只需去掉示例中所有多余的内容,并专注于问题的核心,即绑定(bind):
struct ContentView: View {
@State var selection: [Int] = []
var body: some View {
NavigationView {
Form {
NavigationLink(destination: SelectionView(selection: $selection)) {
Text("Selection: \(selection.count)")
}
}
}
}
}
struct SelectionView: View {
@Binding var selection: [Int]
var body: some View {
NavigationView {
VStack {
Button.init("Append") {
self.selection.append(1)
}
Text("Selection: \(selection.count)")
}
}
}
}
运行示例,点击链接,重复点击按钮。 selection.count
的显示在两个 View 中都发生了变化。这就是您想要的,也正是发生的事情。
这是原始代码的一个变体,它更明确地显示 selection
(而不是 selection.count
),您可以看到正在发生正确的事情:
struct ContentView: View {
@State var selection: [Int] = []
var body: some View {
NavigationView {
Form {
NavigationLink(destination: SelectionView(selection: $selection)) {
Text("Selection: \(String(describing:selection))")
}
}
}
}
}
struct SelectionView: View {
@Binding var selection: [Int]
var body: some View {
NavigationView {
List {
ForEach(0...9, id:\.self) { i in
Button(action: {
if let ix = self.selection.firstIndex(of:i) {
self.selection.remove(at: ix)
} else {
self.selection.append(i)
}
}) {
if self.selection.contains(i) {
Text("Unselect \(i)")
} else {
Text("Select \(i)")
}
}
}
}
}
}
}
关于swift - 如何并行使用@State和@Binding?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57318135/