我有一个内部管理跟踪当前索引的@State 变量的 View 。所以像:
struct ReusableView: View {
@State var index: Int = 0
var body: some View {
Text("The index is \(self.index)"
// A button that changes the index
}
}
此 View 将在整个应用程序中重复使用。有时父 View 需要访问索引,所以我将它重构如下:
struct ParentView: View {
@State var index: Int = 0
var body: some View {
ReusableView($index)
}
}
struct ReusableView: View {
@Binding var index: Int
var body: some View {
Text("The index is \(self.index)"
// A button that changes the index
}
}
问题
我不想将父 View 强制为 总是 保持索引的状态。换句话说,我希望有选择地允许父 View 负责状态变量,但默认使用可重用 View 来维护状态,以防父 View 不关心索引。
试图
我尝试以某种方式初始化可重用 View 上的绑定(bind),以防父 View 不提供绑定(bind):
struct ReusableView: View {
@Binding var index: Int
init(_ index: Binding<Int>? = nil) {
if index != nil {
self._index = index
} else {
// TODO: Parent didn't provide a binding, init myself.
// ?
}
}
var body: some View {
Text("The index is \(self.index)"
// A button that changes the index
}
}
谢谢!
最佳答案
您想要实现的主要问题是,当索引由父级处理时,您的 View 需要对其进行@Binding,但是当它处理索引本身时,它需要@State。有两种可能的解决方案。
如果 View 在没有索引属性时可以忽略它:
struct ReusableView: View {
@Binding var index: Int?
init(_ index: Binding<Int?>) {
self._index = index
}
init() {
self._index = .constant(nil)
}
var body: some View {
VStack {
index.map { Text("The index is \($0)") }
}
}
}
优点是它非常简单——只有两个初始化器,但是当它由 ResusableView 本身处理时,你不能更改索引的值(它是一个常量)。
如果 View 在没有 index 属性时不能忽略它:
struct ReusableView: View {
private var content: AnyView
init(_ index: Binding<Int>? = nil) {
if let index = index {
self.content = AnyView(DependentView(index: index))
} else {
self.content = AnyView(IndependentView())
}
}
var body: some View {
content
}
private struct DependentView: View {
@Binding var index: Int
var body: some View {
Text("The index is \(index)")
}
}
private struct IndependentView: View {
@State private var index: Int = 0
var body: some View {
Text("The index is \(index)")
}
}
}
明显的优势是您有一个可以绑定(bind)到值或将其作为自己的状态管理的 View 。如您所见,ReusableView 只是两个不同 View 的包装器,一个管理自己的@State,一个绑定(bind)到其父 View 的@State。
关于swift - 如何在 SwiftUI 中选择性地传入绑定(bind)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58983538/