提问人:Prasad De Zoysa 提问时间:10/2/2023 最后编辑:Prasad De Zoysa 更新时间:10/2/2023 访问量:86
SwiftUI 表单选取器选项未选择
SwiftUI Form Picker options are not selecting
问:
为什么我无法从此选取器视图中选择项?这里的区别在于我的选择数组由两个不同的结构体('CustomOptionOne'和'CustomOptionTwo')组成,它们符合相同的协议'PickerOption'。编译器给了我两个错误,
类型“any PickerOption”不能符合“Hashable”
静态方法“buildExpression”要求“Content”符合 “辅助功能转子内容”
我怎样才能做到这一点?
任何帮助将不胜感激。
protocol PickerOption: Hashable, Identifiable {
var name: String { get set }
var description: String { get set }
var id: String { get }
}
struct MyView: View {
//I know it's this line, but my array will consist of any object that conforms to PickerOption protocol
private static var exampleStructs: [any PickerOption] = [
CustomOptionOne(name: "Example 1", description: "Example Name 1", id: "5"),
CustomOptionOne(name: "Example 2", description: "Example Name 2", id: "6"),
CustomOptionTwo(name: "Example 3", description: "Example Name 3", id: "7"),
CustomOptionTwo(name: "Example 4", description: "Example Name 4", id: "8")
]
private struct CustomOptionOne: Hashable, Identifiable, PickerOption {
var name: String
var description: String
var id: String
}
private struct CustomOptionTwo: Hashable, Identifiable, PickerOption {
var name: String
var description: String
var id: String
}
@State private var selectedStruct: any PickerOption = CustomOptionOne(name: "Example Name", description: "Example Description", id: "9")
var body: some View {
NavigationView {
Form {
Section(header: Text("Selected Struct")) {
Text(selectedStruct.name)
Text(selectedStruct.description)
}
Section(header: Text("Picker")) {
Picker(selection: $selectedStruct, label: Text(selectedStruct.name), content: {
ForEach(MyView.exampleStructs, id: \.id) { exampleStruct in
Text(exampleStruct.name).tag(exampleStruct)
}
})
}
}
}
}
}
我已经检查了许多答案,包括这个快速选择器没有选择项目,但没有一个回答我的用例场景。
答:
1赞
lorem ipsum
10/2/2023
#1
对于 the 和 must 是完全相同的类型,您的特定示例增加了额外的复杂性,因为您正在尝试将 existentials () 与 SwiftUI 一起使用。Picker
tag
selection
any
因此,最简单的解决方案是同时使用 for 和 ,但首先您必须将 which comes from 限制为特定类型,以便您可以将其匹配为ID
selection
tag
ID
Identifiable
Picker
protocol PickerOption: Hashable, Identifiable where ID == String {
var name: String { get set }
var description: String { get set }
var id: String { get }
}
然后更改属性以使用String
@State private var selectedStructId: String? = nil
然后更改以匹配tag
selectedStructId
Text(exampleStruct.name).tag(exampleStruct.id as String?)
整个事情放在一起看起来会是这样的
struct ContentView: View {
//I know it's this line, but my array will consist of any object that conforms to PickerOption protocol
private static var exampleStructs: [any PickerOption] = [
CustomOptionOne(name: "Example 1", description: "Example Name 1", id: "5"),
CustomOptionOne(name: "Example 2", description: "Example Name 2", id: "6"),
CustomOptionTwo(name: "Example 3", description: "Example Name 3", id: "7"),
CustomOptionTwo(name: "Example 4", description: "Example Name 4", id: "8")
]
private struct CustomOptionOne: PickerOption {
var name: String
var description: String
var id: String
}
private struct CustomOptionTwo: PickerOption {
var name: String
var description: String
var id: String
}
@State private var selectedStructId: String? = nil
var body: some View {
NavigationStack {
Form {
if let selectedStructId, let selectedStruct = ContentView.exampleStructs.filter({ o in
o.id == selectedStructId
}).first{ //Find the selected selected struct
Section(header: Text("Selected Struct")) {
Text(selectedStruct.name)
Text(selectedStruct.description)
}
}
Section(header: Text("Picker")) {
Picker(selection: $selectedStructId, label: Text(""), content: {
Text("Select an object.")
ForEach(ContentView.exampleStructs, id: \.id) { exampleStruct in
Text(exampleStruct.name).tag(exampleStruct.id as String?)
}
})
}
}
}
}
}
我知道这并不理想,但存在主义是与 SwiftUI 的一场艰苦战斗。
评论
0赞
Prasad De Zoysa
10/4/2023
正如你所承认的,这不是一个理想的解决方案。我希望在不从源数组中执行查找的情况下获取所选对象。但是,我知道我们目前没有其他关于存在主义的解决方案。我会接受这个答案,因为它确实在一定程度上解决了原来的问题。谢谢你的努力。
评论
tag
exampleStruct
exampleStruct.id
Static method 'buildExpression' requires that 'Content' conform to 'AccessibilityRotorContent'