我从一个包含国家列表( ID、国家名称和国家缩写)的远程服务器获取一个json。我正在通过ForEach填充带有这些值的选择器。
我无法解决的两个问题是:
我考虑过使用NSPredicate或NSCompoundPredicate,但这只是过滤掉值。我考虑过创建多个获取请求,过滤除美国以外的所有东西,然后其他的显示除美国以外的所有东西。这似乎是一种浪费,我不完全确定如何将它们结合起来。
我可以绑定到这个名字,它工作得很好。同样,我可以将选择器绑定到abbr,并且它可以工作。但是,我不知道如何更新所有3个变量,因为选择器只有一个绑定。我试着编写一个函数,将所有这些变量onTap都设置在ForEach中,但这似乎不是一个好计划(或者可能是?)。
下面是一些代码:
@FetchRequest(sortDescriptors: [SortDescriptor(\.name)] var countries: FetchedResults<Picker_Country>
// Load and decode the JSON from remote URL without caching
func loadCountryData() async {
let config = URLSessionConfiguration.default
config.requestCachePolicy = .reloadIgnoringLocalCacheData
config.urlCache = nil
let URLSessionNoCache = URLSession(configuration: config)
guard let url = URL(string: "https://api.foo.com/general/pickers/country_select") else {
print("Invalid URL")
return
}
do {
let (data, _) = try await URLSessionNoCache.data(from: url)
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
let countries = try decoder.decode([CountryOptions].self, from: data)
await MainActor.run {
setCountryArray(with: countries)
}
} catch {
print("Invalid Data")
}
}
func setCountryArray(with downloadedCountryOptions: [CountryOptions]) {
for countries in downloadedCountryOptions {
let countryPicker = Picker_Country(context: moc)
countryPicker.id = Int16(countries.id)
countryPicker.name = countries.name
countryPicker.abbr = countries.abbr
}
try? moc.save()
}
最后,这是我的选择。
(注意: wrappedName和wrappedAbbr只是允许我不必合并的vars。它们直接对应于名称和缩写)
显然,通过使用.tag,我显示了名称,但只设置了abbr,这也是所选内容的绑定对象。这就是如何在用户选择中设置id、name和abbr的问题。
Picker("Country", selection: $createUser.countryAbbr) {
ForEach(countries) { country in
Text(country.wrappedName).tag(country.wrappedAbbr)
} // End ForEach
} // End Picker
.pickerStyle(WheelPickerStyle())
.padding()
.labelsHidden()
发布于 2022-01-20 07:30:58
其实比我想象的要简单得多。在不使用ForEach的情况下创建选择器时,可以执行以下操作:
Picker("Fooblah", selection: $fooblah) {
Text("foo").tag(0)
Text("blah").tag(1)
} // End Picker
现在,由于JSON存储在CoreData中,而且我们可以使用NSPredicate过滤FetchRequest的结果,因此您可以执行两个FetchRequests,如下所示:
@FetchRequest(sortDescriptors: [], predicate: NSPredicate(format: "abbr == 'US'")) var countryUS: FetchedResults<Picker_Country>
@FetchRequest(sortDescriptors: [SortDescriptor(\.name)], predicate: NSPredicate(format: "abbr != 'US'")) var countries: FetchedResults<Picker_Country>
第一个FetchRequest只返回美国,第二个返回除美国以外的所有内容。
现在,当创建选择器时,执行两个ForEach语句,就像执行两个或多个文本语句一样,如下所示:
Picker("Country", selection: $createUser.countryAbbr) {
ForEach(countryUS) { country in
Text(country.wrappedName).tag(country.wrappedAbbr)
} // End US ForEach
ForEach(countries) { country in
Text(country.wrappedName).tag(country.wrappedAbbr)
} // End All except US ForEach
} // End Picker
使用CoreData并绑定到国家的缩写,然后可以创建关系,以便在managedObjectContext中调用相应的国家名称,就像调用国家缩写一样。
另一个提示是,如果您希望只使用国家缩写,但仍然以某种方式显示整个国家的名称,您可以通过内置区域设置功能这样做,如下所示:
Text(Locale.current.localizedString(forRegionCode: createUser.countryAbbr) ?? createUser.countryAbbr)
现在,这对于您希望在CoreData的选择器中显示的任何类型的结果都是灵活的。只需修改适合您的情况的NSPredicate过滤器即可。
https://stackoverflow.com/questions/70779174
复制相似问题