ree*_*der 8 macos binding state swiftui
我试图在工作表中呈现一个带有 @Binding String 变量的视图,该变量仅在 TextField 中显示/绑定该变量。
在我的主 ContentView 中,我有一个字符串数组,我用 ForEach 循环显示该数组的索引,显示一个按钮,每个按钮都包含循环元素的文本。
按钮操作很简单:将 @State“索引”变量设置为按下的按钮的元素索引并显示工作表。
这是我的内容视图:
struct ContentView: View {
@State var array = ["first", "second", "third"]
@State var showIndex = 0
@State var showSheet = false
var body: some View {
VStack {
ForEach (0 ..< array.count, id:\.self) { i in
Button("\(array[i])") {
showIndex = i
showSheet = true
}
}
// Text("\(showIndex)") // if I uncomment this line, it works!
}
.sheet(isPresented: $showSheet, content: {
SheetView(text: $array[showIndex])
})
.padding()
}
}
Run Code Online (Sandbox Code Playgroud)
这是 SheetView:
struct SheetView: View {
@Binding var text: String
@Environment(\.presentationMode) var presentationMode
var body: some View {
VStack {
TextField("text:", text: $text)
Button("dismiss") {
presentationMode.wrappedValue.dismiss()
}
}.padding()
}
}
Run Code Online (Sandbox Code Playgroud)
问题是,当我第一次打开应用程序并按“第二个”按钮时,工作表将打开并在文本字段中显示“第一个”。然后我可以关闭工作表并再次按“第二个”按钮,得到相同的结果。
如果我按下“第三个”或“第一个”按钮,从那时起一切都会正常。按任何按钮都会产生正确的行为。
有趣的是,如果我取消注释带有显示 showIndex 变量的文本的行,它从第一次就可以工作。
这是一个错误,还是我在这里做错了什么?
您应该使用自定义 Binding、自定义 Struct 来解决问题,这是一个复杂的问题。参见示例:
struct ContentView: View {
@State private var array: [String] = ["first", "second", "third"]
@State private var customStruct: CustomStruct?
var body: some View {
VStack {
ForEach (array.indices, id:\.self) { index in
Button(action: { customStruct = CustomStruct(int: index) }, label: {
Text(array[index]).frame(width: 100)
})
}
}
.frame(width: 300, height: 300, alignment: .center)
.background(Color.gray.opacity(0.5))
.sheet(item: $customStruct, content: { item in SheetView(text: Binding.init(get: { () -> String in return array[item.int] },
set: { (newValue) in array[item.int] = newValue }) ) })
}
}
struct CustomStruct: Identifiable {
let id: UUID = UUID()
var int: Int
}
struct SheetView: View {
@Binding var text: String
@Environment(\.presentationMode) var presentationMode
var body: some View {
VStack {
TextField("text:", text: $text)
Button("dismiss") {
presentationMode.wrappedValue.dismiss()
}
}.padding()
}
}
Run Code Online (Sandbox Code Playgroud)
我以前也遇到过这种情况。我相信这是一个错误,因为在 UI 中使用它之前,它似乎没有在 ForEach 中设置。我基本上以与您相同的方式修复了它,但有一点微妙。在每个中使用它Button作为 的一部分Label,但将其隐藏起来,如下所示:
Button(action: {
showIndex = i
showSheet = true
}, label: {
HStack {
Text("\(array[i])")
Text(showIndex.description)
.hidden()
}
})
Run Code Online (Sandbox Code Playgroud)
这不会改变您的 UI,但您使用它时它会得到正确更新。我似乎找不到我的应用程序中出现问题的位置,并且我更改了用户界面以摆脱此问题,但我不记得我是如何做到的。如果我能找到它,我会更新它。这有点拼凑,但它确实有效。