首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >选择器中的SwiftUI FetchRequest命令输出

选择器中的SwiftUI FetchRequest命令输出
EN

Stack Overflow用户
提问于 2022-01-19 23:44:32
回答 1查看 133关注 0票数 0

我从一个包含国家列表( ID、国家名称和国家缩写)的远程服务器获取一个json。我正在通过ForEach填充带有这些值的选择器。

我无法解决的两个问题是:

  1. I想显示美国是挑选者的第一选择,然后是所有其他国家的字母列表。

我考虑过使用NSPredicate或NSCompoundPredicate,但这只是过滤掉值。我考虑过创建多个获取请求,过滤除美国以外的所有东西,然后其他的显示除美国以外的所有东西。这似乎是一种浪费,我不完全确定如何将它们结合起来。

  1. 基于用户的选择,我需要填充三个变量(id、name和abbr)。

我可以绑定到这个名字,它工作得很好。同样,我可以将选择器绑定到abbr,并且它可以工作。但是,我不知道如何更新所有3个变量,因为选择器只有一个绑定。我试着编写一个函数,将所有这些变量onTap都设置在ForEach中,但这似乎不是一个好计划(或者可能是?)。

下面是一些代码:

代码语言:javascript
代码运行次数:0
运行
复制
@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的问题。

代码语言:javascript
代码运行次数:0
运行
复制
Picker("Country", selection: $createUser.countryAbbr) {
    ForEach(countries) { country in
        Text(country.wrappedName).tag(country.wrappedAbbr)
    } // End ForEach
} // End Picker
.pickerStyle(WheelPickerStyle())
.padding()
.labelsHidden()
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-20 15:30:58

其实比我想象的要简单得多。在不使用ForEach的情况下创建选择器时,可以执行以下操作:

代码语言:javascript
代码运行次数:0
运行
复制
Picker("Fooblah", selection: $fooblah) {
    Text("foo").tag(0)
    Text("blah").tag(1)
} // End Picker

现在,由于JSON存储在CoreData中,而且我们可以使用NSPredicate过滤FetchRequest的结果,因此您可以执行两个FetchRequests,如下所示:

代码语言:javascript
代码运行次数:0
运行
复制
@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语句,就像执行两个或多个文本语句一样,如下所示:

代码语言:javascript
代码运行次数:0
运行
复制
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中调用相应的国家名称,就像调用国家缩写一样。

另一个提示是,如果您希望只使用国家缩写,但仍然以某种方式显示整个国家的名称,您可以通过内置区域设置功能这样做,如下所示:

代码语言:javascript
代码运行次数:0
运行
复制
Text(Locale.current.localizedString(forRegionCode: createUser.countryAbbr) ?? createUser.countryAbbr)

现在,这对于您希望在CoreData的选择器中显示的任何类型的结果都是灵活的。只需修改适合您的情况的NSPredicate过滤器即可。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70779174

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档