swift - 如何并行使用@State和@Binding?

标签 swift user-interface swiftui

我的设置: 我有一个 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)")
                        }
                    }
                }
            }
        }
    }
}

enter image description here

关于swift - 如何并行使用@State和@Binding?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57318135/

相关文章:

ios - 如何过滤 Google Places API 自动完成数据以获取国家/地区和州

swift - Swift 中的单例

android - 如何使用 getResource.getIdentifier() 获取布局?

foreach - 如何使用 SwiftUI 在 ScrollView 中选择一个项目?

ios - 如何使用pushViewController从UIHostingController的SwiftUI View 内部推送ViewController?

swift - 快速滚动的标签栏

ios - 如何将一张图片放在另一张图片前面?

c# - 调用方法的结果到主线程

java - 如何制作一个猜数字游戏

ios - 如何在 SwiftUI 中恢复与 UIKit (interactivePopGestureRecognizer) 中相同的行为