如何在 Swift UI 中将嵌套的 JSON 值显示到选取器视图中?

Posted

技术标签:

【中文标题】如何在 Swift UI 中将嵌套的 JSON 值显示到选取器视图中?【英文标题】:How to show Nested JSON values into the pickerview in Swift UI? 【发布时间】:2020-08-14 12:20:15 【问题描述】:

我希望用户选择该城市的城市和地区。当我选择城市时,我想在选择器视图中列出该城市的地区。我还想在Text中显示城市的选择和地区的选择。

struct locationView: View 


@State var selectedFrameworkIndex = 0
@State var tap1 : Bool = false

@ObservedObject var cityfetch = cityFetcher()

var selectedCityName: String? 
    if !cityfetch.cities.isEmpty && selectedFrameworkIndex < cityfetch.cities.count 
        return cityfetch.cities[selectedFrameworkIndex].city_name
     else 
        return nil
    


var body: some View 
    
          
            VStack
                
                
                Picker(selection: $selectedFrameworkIndex, label: Text("")) 
                    ForEach(0 ..< cityfetch.cities.count, id: \.self) 
                        
                        Text(self.cityfetch.cities[$0].city_name)
                    
                .padding(.trailing, 50)
                    .id(UUID())
                
                
                Picker(selection: $selectedFrameworkIndex, label: Text(""))
                    ForEach(0 ..< cityfetch.cities.count, id: \.self) 
                        
                        Text(self.cityfetch.cities[$0].district_name)
                    
                .padding(.trailing, 50)
                    .id(UUID())
                
            
            
            
            
            Text("Seçiminiz: \(selectedCityName ?? "")")
                .font(.system(size: 20, weight: .regular, design: .rounded))
            
            
        

struct city : Decodable, Identifiable

let id = UUID()
let city_id : Int
let city_name : String
let district_id : Int
let district_name : String

我的班级正在关注..

class cityFetcher : ObservableObject

@Published var cities = [city]()


init() 
    loadCity()
    

func loadCity()
    
    let url = URL(string: "https://raw.githubusercontent.com/midorikocak/turkish-cities-districts/master/data/il-ilce.json")
    URLSession.shared.dataTask(with: url!)  (data, response, error) in
        do
            let cities = try JSONDecoder().decode([city].self, from: data!)
            DispatchQueue.main.async 
                self.cities = cities
                
            
                
            
           catch
            print("Error")
        
    .resume()
    
    

我还将我的 JSON 信息发布为图像。

【问题讨论】:

这里你需要做很多事情,但对于初学者来说,因为你的 json 包含重复的城市,你不能直接在选择器中使用它,因为它会包含许多“Adana”。所以你需要先把它转换成不同的结构,去掉重复的城市,这样你就可以为每个城市得到属于该城市的地区 【参考方案1】:

cityFetcher 中添加函数getUniqiueCities() 以创建唯一城市数组并在self.cities = cities 之后调用此函数。在cityFetcher 中创建@Published var uniqueCities : [city] = []

func getUniqiueCities() 
        var uniqueCities: [city] = []
        for city in self.cities 
            let isExists =  uniqueCities.contains item in
                return item.city_name == city.city_name
            
            if !isExists 
              uniqueCities.append(city)
            
        
        self.uniqueCities =  uniqueCities
    

unique cities 运行一个循环,并根据唯一的城市名称显示区域。 使用以下代码更新LocationView

struct locationView: View 
    @State var selectedFrameworkIndex = 0
    @State var selectedCityIndex = 0
    @State var tap1 : Bool = false
    @ObservedObject var cityfetch = cityFetcher()

    var selectedCityName: String? 
        if !self.cityfetch.uniqueCities.isEmpty && selectedFrameworkIndex < self.cityfetch.uniqueCities.count 
            return self.cityfetch.uniqueCities[selectedFrameworkIndex].city_name
         else 
            return nil
        
    

    var body: some View 
        VStack
            Picker(selection: $selectedFrameworkIndex, label: Text("")) 
                ForEach(0 ..< self.cityfetch.uniqueCities.count, id: \.self) 
                    Text(self.cityfetch.uniqueCities[$0].city_name)
                
            .padding(.trailing, 50)
            .id(UUID())
            Picker(selection: $selectedCityIndex, label: Text(""))
                ForEach(0 ..< self.getFilteredDistricts().count, id: \.self) 
                    Text(self.getFilteredDistricts()[$0].district_name)
                
            .padding(.trailing, 50)
            .id(UUID())
            
        
                  
        Text("Seçiminiz: \(selectedCityName ?? "")")
            .font(.system(size: 20, weight: .regular, design: .rounded))
        
    
    
    func getFilteredDistricts() -> [city] 
        return self.cityfetch.cities.filter($0.city_name == self.cityfetch.uniqueCities[selectedFrameworkIndex].city_name)
    
    

更新

根据 cmets,添加代码以获取 selectedDistrict:

var selectedDistrict: String? 
        if !self.getFilteredDistricts().isEmpty && selectedCityIndex < self.getFilteredDistricts().count 
            return self.getFilteredDistricts()[selectedCityIndex].district_name
         else 
            return nil
        
    

【讨论】:

非常感谢您的回答。它按我的预期工作。赞赏。 我注意到 Text("Seçiminiz: (selectedCityName ?? "")") 部分无法正常工作,当我选择不同的城市时,文本中的值不会改变。我还想在所选城市名称文本下显示选择的区域。你能帮我解决这个问题吗? 让我查一下,会通知你的 更新了我的代码,添加了代码以获取选定的地区。请检查,我在显示所选城市名称时没有发现任何问题。它非常适合我。 @Ozan 感谢您对所选地区部分的回答。它按我的预期工作,但仍然存在与 selectedCityName 部分相关的问题。如果我在选择器中更改城市,文本不会因此而改变。

以上是关于如何在 Swift UI 中将嵌套的 JSON 值显示到选取器视图中?的主要内容,如果未能解决你的问题,请参考以下文章

如何在swift中将json数组保存和检索到用户默认值?

从嵌套结构 swift ui 创建列表

如何在 swift 4 中使用 JSONDecoder 从嵌套 JSON 中获取数据?

如何在 Swift 3.0 中将 TableViewCell 值传递给新的 ViewController?

如何在bigquery中将一个json列嵌套在另一个列中

如何在 Swift 4.0 中将 JSON 输出设置为 UILabel?