macos - 首次呈现时,带有 Binding 变量的 SwiftUI 呈现表不起作用
问题描述
我正在尝试使用 @Binding 字符串变量在工作表中显示视图,该变量仅在 TextField 中显示/绑定此变量。
在我的主 ContentView 中,我有一个字符串数组,我用 ForEach 循环显示数组的索引,显示一个按钮,每个按钮都带有循环元素的文本。
Buttons 操作很简单:为按下的 Buttons 的 Element-index 设置一个 @State "index"-variable 并显示工作表。
这是我的内容视图:
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()
}
}
这是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()
}
}
问题是,当我第一次打开应用程序并按下“第二个”按钮时,工作表会打开并在 TextField 中显示“第一个”。然后我可以关闭工作表并再次按下“第二个”按钮,结果相同。
如果我然后按下“第三个”或“第一个”按钮,那么从那时起一切正常。按下任何按钮都会导致正确的行为。
有趣的是,如果我取消注释带有显示 showIndex 变量的文本的行,它从第一次开始就起作用。
这是一个错误,还是我在这里做错了什么?
解决方案
You should use custom Binding, custom Struct for solving the issue, it is complex issue. See the Example:
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()
}
}
推荐阅读
- java - 如何自定义我的 log4j2.xml 参数
- python - 有没有办法在 python 中发送/按下 NUMPAD 键?
- c# - 递归方法的 IEnumerable 比使用 foreach 构造的相同 IEnumerable 慢 10 倍
- sql-server - SQL Server 2017 触发器 - 声明变量
- android - 在运行时验证 android 库的 (aar) 签名
- c - Windows 桌面 API 和 C 运行时库之间的区别?
- javascript - 如何使用 showErrors 函数显示集中的错误消息并更改输入边框颜色
- php - 仅当 url 中没有其他参数时才使用 htaccess 路由
- swift - Swift Generic Type Equatable 通过对数组进行排序
- r - 我怎样才能使数据框中的一个因素永久地成为数字?