Jim*_*Jim 3 json picker swiftui xcode11 observedobject
我是移动开发新手,正在学习 SwiftUI。
我一直在努力找出我的选择器出了什么问题。我成功从 URLSession 返回数据,并将其添加到我的模型中。我可以通过将 @ObservedObject 添加到列表来确认这一点,该列表返回所有项目。由于某种原因,将相同的 @ObservedObject 放入选择器会返回空选择器。任何帮助,将不胜感激。谢谢。
这是我对 Picker() 的看法。运行时,选择器为空。我可以注释掉 Picker(),只留下 ForEach() 和 Text(),然后文本就会出现。
import Foundation
import Combine
import SwiftUI
struct ContentView: View {
@ObservedObject var countries = CulturesViewModel()
@State private var selectedCountries = 0
var body: some View {
VStack {
//loop through country array and add them to picker
Picker(selection: $selectedCountries, label: Text("Select Your Country")) {
ForEach(0 ..< countries.cultures.count, id: \.self) { post in
Text(self.countries.cultures[post].Culture).tag(post)
}
}.labelsHidden()
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的视图模型。它将 @Published 变量设置为 WebService() 中 JSON 请求的结果。如果我将 @Published 变量硬编码为开始返回的值,则选择器将起作用。
import Foundation
import Combine
import SwiftUI
class CulturesViewModel: ObservableObject {
init() {
fetchCultures()
}
@Published var cultures = [Culture](){
didSet {
didChange.send(self)
}
}
private func fetchCultures(){
WebService().GetCultures {
self.cultures = $0
}
}
let didChange = PassthroughSubject<CulturesViewModel, Never>()
}
Run Code Online (Sandbox Code Playgroud)
这是我的 WebService()。不幸的是,我无法共享 JSON url,我已添加到返回的 json 中。
import Foundation
import SwiftUI
import Combine
class WebService {
func GetCultures(completion: @escaping([Culture]) ->()) {
guard let url = URL("")
[
{
"CultureId": 0,
"Culture": "Select Your Country"
},
{
"CultureId": 1078,
"Culture": "English (United States)"
},
{
"CultureId": 6071,
"Culture": "English (Canada)"
}
]
URLSession.shared.dataTask(with: url) { (data,_,_) in
do {
if let data = data {
let culturesList = try JSONDecoder().decode([Culture].self, from: data)
DispatchQueue.main.async {
completion(culturesList)
}
} else {
DispatchQueue.main.async {
completion([])
}
}
} catch {
print(error)
DispatchQueue.main.async {
completion([])
}
}
}.resume()
}
}
Run Code Online (Sandbox Code Playgroud)
最后,这是我的模型。
import Foundation
struct Culture: Codable, Identifiable {
var id = UUID()
var CultureId: Int
var Culture: String
}
Run Code Online (Sandbox Code Playgroud)
使选择器刷新的解决方法是添加唯一的 ID。刷新(或)重新加载国家/地区将为选择器项目创建一个新的 UUID。这将强制选择器刷新。我已经修改了您的代码以包含 id。
//loop through country array and add them to picker
Picker(selection: $selectedCountries, label: Text("Select Your Country")) {
ForEach(0 ..< countries.cultures.count, id: \.self) { post in
Text(self.countries.cultures[post].Culture).tag(post)
}
}.labelsHidden()
.id(UUID())
Run Code Online (Sandbox Code Playgroud)
这似乎是选择器的一个已知问题。
| 归档时间: |
|
| 查看次数: |
245 次 |
| 最近记录: |