我正在玩SwiftUI,显然没有得到它。
有效的示例,仅显示所选名称。
struct ContentView: View {
let names = ["Joe", "Jim", "Paul"]
@State var selectedName = Set<String>()
var body: some View {
VStack {
List(names, id: \.self, selection: $selectedName) { name in
Text(name)
}
if !selectedName.isEmpty {
Text(selectedName.first!) // <-- this line
}
}
}
}
我想要的是一个可以更改名称的文本字段。尝试了很多方法,但是每次都会遇到另一个错误。
TextField("Name", text: $selectedName)
给出此错误:无法将类型'Binding
>'的值转换为预期的参数类型'Binding '
TextField("Name", text: $selectedName.first!)
不能强制打开非可选类型'Binding <(((String)throws-> Bool)throws-> String?>''
我该怎么做?
答案 0 :(得分:0)
很显然,您无法将Binding<Set<String>>
传递给Binding<String>
。这里给出了一个使用TextField更改selectedName变量的想法或解决方案:
我添加了一个新变量Binding<String>
。然后,在TextField的onCommit
闭包中更改selectedName。
struct ContentView: View {
let names = ["Joe", "Jim", "Paul"]
@State var selectedName = Set<String>()
@State var textFieldName = ""
var body: some View {
VStack {
List(names, id: \.self, selection: $selectedName) { name in
Text(name)
}
if !selectedName.isEmpty {
Text(selectedName.first!)
}
Text(textFieldName)
TextField("Name", text: $textFieldName, onEditingChanged: { (Bool) in
//onEditing
}) {
//onCommit
self.selectedName.insert(self.textFieldName)
}
}
}
}
答案 1 :(得分:0)
您可以自己进行绑定:
TextField("Name", text: Binding<String>(get: {self.selectedName.first!}, set: { _ in}) )
答案 2 :(得分:0)
好的,如果我需要编辑一个屏幕中的names
值,并列出并编辑字段,并使它们全部同步而不彼此混淆,这是我的替代方法。
这里是完整的可测试模块(已在Xcode 11.2 / iOS 13.2上测试)。当我在iOS上进行测试时,API要求将List
放入EditMode来处理选择,因此包括在内。
struct TestChangeSelectedItem: View {
@State var names = ["Joe", "Jim", "Paul"] // made modifiable
@State var selectedName: String? = nil // only one can be edited, so single selection
@State var editMode: EditMode = .active // Tested for iOS, so it is needed
var body: some View {
VStack {
List(selection: $selectedName) {
ForEach(names, id: \.self) { name in
Text(name)
}
}
.environment(\.editMode, $editMode) // Tested for iOS, so it is needed
if selectedName != nil {
Divider()
Text(selectedName!) // Left to see updates for selection
editor(for: selectedName!) // Separated to make more clear
}
}
}
private func editor(for selection: String) -> some View {
let index = names.firstIndex(of: selection)!
var editedValue = selection // local to avoid cycling in refresh
return HStack {
Text("New name:")
TextField("Name", text: Binding<String>(get: { editedValue }, set: { editedValue = $0}), onCommit: {
self.names[index] = editedValue
self.selectedName = editedValue
})
}
}
}
struct TestChangeSelectedItem_Previews: PreviewProvider {
static var previews: some View {
TestChangeSelectedItem()
}
}