问题描述
我是SwiftUI和编码的新手,如果之前已经介绍过,请对不起。我确实进行了搜索,但找不到足够清楚的信息。
我正在尝试制作一个用于存储笔记和任务的应用程序。 (我不打算将其发布在商店上,我对此还太新手,但是我确实想学习Swift,并且对实际应用程序的开发对我来说比阅读它更有用。)我有一个实体,称为具有8个属性的“基本”并选择了自动Codegen类定义。我更喜欢保持这种方式,请不要手动。
我有三个提取请求。一个可以让我从核心数据中获取所有数据。其他两个过滤器将一个属性称为campoEstado。现在,在campoEstado中,我仅将两个可能的值之一存储为字符串:“ Activas”和“ Pospuestas”。将来我可能会添加更多,所以我不能为此使用布尔值。
我得到一个处理一个提取请求的列表。但是当应用程序运行时,我无法更改该来源。 我用.pickerStyle(SegmentedPickerStyle())制作了一个选择器,向我显示:Todo,Activas和Pospuestas。当用户在选择器中选择此选项卡之一时,列表应更改为:
- 选项卡1:所有任务
- 表2:仅包含campoEstado =“ Activas”的任务的过滤列表(调用获取请求filtroActivas)
- 标签3:仅包含带有campoEstado =“ Pospuestas”的任务的过滤列表(调用提取请求filtroPospuestas)
它的外观:
我在ContentView中的代码:
struct ContentView: View {
@Environment(\.managedobjectContext) var moc
@FetchRequest(entity: Base.entity(),sortDescriptors: [
NSSortDescriptor(keyPath: \Base.campoNota,ascending: true),NSSortDescriptor(keyPath: \Base.campoFechaCreacion,ascending: true)
],predicate: nspredicate(format: "campoEstado == %@","Activas")
) var filtroActivas: FetchedResults<Base>
@FetchRequest(entity: Base.entity(),"Pospuestas")
) var filtroPospuestas: FetchedResults<Base>
@FetchRequest(entity: Base.entity(),ascending: true)
]
) var bases: FetchedResults<Base>
var body: some View {
NavigationView {
List {
Picker("Solapas",selection: $selectorIndex) {
//This should connect to ForEach source,currently "bases"
}
.pickerStyle(SegmentedPickerStyle())
ForEach(bases,id: \.self) { lista in
NavigationLink(destination: VistaEditar(base: lista)) {
Rectangle()
.foregroundColor(.gray)
.frame(width: 7,height: 50)
vstack(alignment: .leading) {
Text(lista.campoNota ?? "UnkNown title")
.font(.headline)
Text(lista.campoEstado ?? "Activas")
}
}
}
我有两个问题:
-
我不知道如何将选择器中的选定选项卡与List内的ForEach源连接起来
-
我使列表适用于一个提取请求,该提取请求使我获得了Core Data中的每条记录,但是我不知道如何在应用程序运行时更改ForEach源。我为获取请求的每个变量名称(基,filtroActivas和filtroPospuestas)尝试了一组变量名称数组,但将它们放在[]中,但这没用。
我知道这并不优雅,我只需要先工作然后再追求效率和优雅即可。我确定我没有看到一些愚蠢的东西,但是已经过去了一个星期,我变得绝望了。
我希望我很清楚,如果您需要更多信息,请询问。 如果有人可以帮助我,我将非常感谢。预先感谢!
解决方法
我担心我对此可能会感到沮丧,因为这不是一个完整的答案。但是我没时间了,我想看看是否能为您提供正确的方向。
我相信您正在寻找的是数组数组。 FetchedResult
将返回一个可选数组,您要确保它不是nil。我在示例中使用compactMap
生成了示例数组的非null数组,这些数组用于模拟您从@FetchRequest
属性中得到的结果。您应该能够将此代码加载到Xcode中的新项目中以查看结果。同样,这不是一个完整的答案,但希望会对您的项目有所帮助。我希望这会有所帮助,继续努力,一定会成功的!
struct ContentView: View {
// Sample data to mimic optional FetchedResults coming from CoreData.
// These are your @FetchRequest properties
let fetchedResultsBases: [String?] = ["Red","Green","Blue"]
let fetchedResultsFiltroPospuestas: [String?] = ["1","2","3"]
let fetchedResultsFiltroActivas: [String?] = ["☺️","?","?"]
// Options for your picker
let types = ["Bases","Pospuestas","Activas"]
@State private var groups = [[String]]()
@State private var selection = 0
var body: some View {
NavigationView {
VStack {
Picker("Solapas",selection: $selection) {
ForEach(0..<types.count,id: \.self) {
Text("\(self.types[$0])")
}
}.pickerStyle(SegmentedPickerStyle())
List {
ForEach(0..<groups.count,id: \.self) { group in
Text("\(self.groups[self.selection][group])")
}
}
}
}
.onAppear(perform: {
self.loadFetchedResults()
})
} // This is the end of the View body
func loadFetchedResults() {
// This is where you'll create your array of fetchedResults,then add it to the @State property.
var fetchedResults = [[String]]()
// Use compact map to remove any nil values.
let bases = fetchedResultsBases.compactMap { $0 }
let pospuestas = fetchedResultsFiltroPospuestas.compactMap { $0 }
let filtroActivas = fetchedResultsFiltroActivas.compactMap { $0 }
fetchedResults.append(bases)
fetchedResults.append(pospuestas)
fetchedResults.append(filtroActivas)
groups = fetchedResults
}
} // This is the end of the ContentView struct