2

我是移动开发新手,正在学习 SwiftUI。

我一直在努力弄清楚我的选择器出了什么问题。我成功地从我的 URLSession 返回数据,并将其添加到我的模型中。我可以通过将我的@ObservedObject 添加到返回所有项目的列表来确认这一点。出于某种原因,将相同的 @ObservedObject 放入选取器会返回一个空的选取器。任何帮助,将不胜感激。谢谢。

这是我对 Picker() 的看法。运行时,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()
    }
}

这是我的视图模型。它将@Published 变量设置为WebService() 中JSON 请求的结果。如果我将 @Published 变量硬编码为开始返回的值,则 Picker 工作。

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

这是我的 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()
    }
}

最后,这是我的模型。

import Foundation

struct Culture: Codable, Identifiable {
    var id = UUID()
    var CultureId: Int
    var Culture: String
}
4

1 回答 1

5

使选择器刷新的解决方法是添加一个唯一的 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())

这似乎是选择器的一个已知问题。

于 2020-03-10T19:11:18.917 回答