微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

SwiftUI加载JSON文件并在视图加载时对其进行过滤

如何解决SwiftUI加载JSON文件并在视图加载时对其进行过滤

我正在尝试在应用程序中提供受支持的国家/地区列表,过滤器可能稍后会来自WS,或者可能会以国家/地区代码的形式保留在我的代码中。

我是SwiftUI的新手,我想做的是使用所有国家/地区名称,他们的电话代码和国家/地区代码过滤JSON文件,并且在研究了一些代码之后,这个:

struct CountryCodePicker: View {
    let includedCountries = ["MX","US","CA"]
    var countryCode = Locale.current.regionCode ?? "MX"
    let allCountries: [Country] = load("countryCodes.json")
    
    @State var countries: [Country]
    @State var showingCountriesList: Bool = false
    @State private var dialCode: String = "+1"
    @State var phoneNumber: String
    @State var isActive: Bool = false
    
    func getDialCode() -> String {
        countries = allCountries.filter {includedCountries.contains($0.code)}
        
        print(countries)
        
        for country in countries where country.code == countryCode {
            return country.dialCode
        }
        return self.dialCode
    }
    
    var body: some View {
        HStack {
            Button(action: {
                self.showingCountriesList.toggle()
            }) {
                HStack() {
                    Image(countryCode,bundle: FlagKit.assetBundle)
                        .renderingMode(.original)
                        .resizable()
                        .frame(width: 36,height: 24)
                        .aspectRatio(contentMode: .fit)
                        .offset(x: 0,y: -6)
                    
                    Text(getDialCode())
                        .baselineOffset(12)
                        .foregroundColor(ColorManager.Grey500)
                        .titleStyle()
                }
            }.sheet(isPresented: $showingCountriesList) {
                CountriesList(countryList: self.countries)
            }
            UnderscoredTextField(phoneNumber: "")
        }
    }
}

struct CountryCodePicker_Previews: PreviewProvider {
    static var previews: some View {
        CountryCodePicker(countries: [Country(name: "United States",dialCode: "+1",code: "US")],phoneNumber: "12345678")
    }
}

产生此输出

enter image description here

Country模型如下:

struct Country: Codable {
    let name: String
    let dialCode: String
    let code: String
    
    enum CodingKeys: String,CodingKey {
        case name = "name"
        case dialCode = "dial_code"
        case code = "code"
    }
    
    init(name: String,dialCode: String,code: String) {
        self.name = name
        self.dialCode = dialCode
        self.code = code
    }
}

我知道它包含一些额外的视图,但是您对程序的运行方向有所了解,在getDialCode()的第一行我收到一条紫色警告,指出:

Modifying state during view update,this will cause undefined behavior.

我相信这是因为它可能现在可以工作,但是在某些情况下某些设备上的行为可能有所不同。

有人可以解释进行国家/地区过滤的正确方法是什么?我需要稍后将此过滤后的数组发送到模式视图,以防用户在点击标志时不得不更改其国家/地区。

解决方法

我通过移动来固定它:

let allCountries: [Country] = load("countryCodes.json")
let includedCountries = ["MX","US","CA"]

func filterCountries() -> [Country] {
    return allCountries.filter{includedCountries.contains($0.code)}
}

CountryCodePicker(countries: self.filterCountries())

致我的ContentView

我的CountryCodePicker现在变成:

struct CountryCodePicker: View {
    @State var countries: [Country]
    @State private var countryCode = Locale.current.regionCode ?? "US"
    @State private var dialCode: String = "+1"
    @State private var showingCountriesList: Bool = false
    
    func getDialCode() -> String {
        for country in countries where country.code == countryCode {
            return country.dialCode
        }
        return self.dialCode
    }
    
    var body: some View {
        HStack {
            Button(action: {
                self.showingCountriesList.toggle()
            }) {
                HStack() {
                    Image(countryCode,bundle: FlagKit.assetBundle)
                        .renderingMode(.original)
                        .resizable()
                        .frame(width: 36,height: 24)
                        .aspectRatio(contentMode: .fit)
                        .offset(x: 0,y: -6)
                    
                    Text(getDialCode())
                        .baselineOffset(12)
                        .foregroundColor(ColorManager.Gray200)
                        .titleStyle()
                }
            }.sheet(isPresented: $showingCountriesList) {
                CountriesList(countryList: self.countries)
            }
            UnderscoredTextField(phoneNumber: "")
        }
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。