首页 > 解决方案 > 首次呈现时,带有 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 变量的文本的行,它从第一次开始就起作用。

这是一个错误,还是我在这里做错了什么?

标签: macosswiftuibindingstate

解决方案


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()
    }
}

enter image description here


推荐阅读