如何在 SwiftUI 中使用 ObservedObject 制作 Picker? [英] How make work a Picker with an ObservedObject in SwiftUI?
问题描述
我正在尝试从 Rest API 获取数据中心列表并将它们显示在选择器中,以便用户可以选择一个.当我用静态列表做它时,它工作正常.但是,动态检索数据中心似乎效果不佳.
I'm trying to get a list of Datacenters from a Rest API and show them in a Picker, so the user can choose one. When I do it with a static list it works fine. However, retrieving the Datacenters dinamically seems not to work fine.
我使用的是 Xcode 11 (GM)
I'm using Xcode 11 (GM)
这是数据中心对象
struct Datacenter:Codable, Hashable, Identifiable{
let id: String
var location: String
}
这是 ObservedObject(它的属性 datacenters 是一个 Datacenter 对象数组)
This is the ObservedObject (it has the property datacenters that is an array of Datacenter objects)
@ObservedObject var datacenters_controller : DatacentersController
@State private var selectedDatacenter = 0
这是我的第一次尝试:
Picker(selection: $selectedDatacenter, label: Text("Datacenter")) {
ForEach(0 ..< datacenters_controller.datacenters.count) {
Text(self.datacenters_controller.datacenters[$0].location)
}
}
Swift 抱怨以下错误:
Swift complained with the following error:
ForEach<Range<Int>, Int, Text> count (4) != its initial count (0). `ForEach(_:content:)` should only be used for *constant* data. Instead conform data to `Identifiable` or use `ForEach(_:id:content:)` and provide an explicit `id`!
然后我切换到:
Picker(selection: $selectedDatacenter, label: Text("Datacenter")) {
ForEach(datacenters_controller.datacenters) { datacenter in
Text(datacenter.location)
}
}
它有效"(没有错误),但结果不是预期的,因为虽然我可以选择一个数据中心,但它没有存储",也没有显示在选择器中.
It "works" (no error), but the result is not the expected because although I can select a datacenter, it is not "stored", not shown in the Picker as selected.
实际结果
预期结果
有什么想法吗?我做错了什么?
Any idea? What I'm doing wrong?
推荐答案
这是一个工作示例.关键是 selectedDatacenter 需要与 Datacenter.id 的类型相同(在本例中为 String).
Here's a working example. The key is that selectedDatacenter needs to be the same type as Datacenter.id (in this case, String).
struct ContentView: View {
@ObservedObject var datacenters_controller = DatacentersController()
@State private var selectedDatacenter = ""
var body: some View {
NavigationView {
Form {
Picker(selection: $selectedDatacenter, label: Text("Datacenter")) {
ForEach(datacenters_controller.datacenters) { datacenter in
Text(datacenter.location)
}
}
// Just here for demonstration
Text("selectedDatacenter (id): \(selectedDatacenter.isEmpty ? "Nothing yet" : selectedDatacenter)")
}
}
}
}
这是支持代码
struct Datacenter:Codable, Hashable, Identifiable{
let id: String
var location: String
}
class DatacentersController: ObservableObject {
@Published var datacenters: [Datacenter] = []
init() {
datacenters = [
Datacenter(id: "ABQ", location: "Albuquerque"),
Datacenter(id: "BOS", location: "Boston"),
Datacenter(id: "COS", location: "Colorado Springs")
]
}
}
这篇关于如何在 SwiftUI 中使用 ObservedObject 制作 Picker?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!