0

我是 SwiftUI 和一般编码的新手,如果之前已经介绍过,我很抱歉。我确实搜索过它,但我找不到它足够清楚。

我正在尝试制作一个用于存储笔记和任务的应用程序。(我不打算把它放在商店里,我太新手了,但我确实想学习 Swift 并且开发一个实际的应用程序对我来说比阅读它更有用。)我有一个名为“基础”具有 8 个属性和选择的自动 Codegen 类定义。我更喜欢保持这种方式,请不要使用手册。

我有三个获取请求。一个从 Core Data 获取所有数据。另外两个过滤一个名为 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(), sortDescriptors: [
        NSSortDescriptor(keyPath: \Base.campoNota, ascending: true),
        NSSortDescriptor(keyPath: \Base.campoFechaCreacion, ascending: true)
    ], predicate: NSPredicate(format: "campoEstado == %@", "Pospuestas")
    ) var filtroPospuestas: FetchedResults<Base>

     @FetchRequest(entity: Base.entity(), sortDescriptors: [
        NSSortDescriptor(keyPath: \Base.campoNota, ascending: true),
        NSSortDescriptor(keyPath: \Base.campoFechaCreacion, 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")
                        }
                    }
                }

我有两个问题:

  1. 我不知道如何将选择器中的选定选项卡与列表中的 ForEach 源连接

  2. 我使列表适用于一个获取请求,它为我带来了 Core Data 中的每条记录,但我不知道如何在应用程序运行时更改 ForEach 源。我已经为每个提取请求变量名称(bases、filtroActivas 和 filtroPospuestas)尝试了一组变量名称,将它们放在 [] 中,但这不起作用。

我知道这并不优雅,我只需要它先工作,然后再追求效率和优雅。我敢肯定有一些愚蠢的事情我没有看到,但已经一个星期了,我越来越绝望了。

我希望我很清楚,如果您需要更多信息,请询问。如果有人可以帮助我,我将不胜感激。提前致谢!

4

1 回答 1

0

我担心我可能会因此而被否决,因为这不是一个完全完整的答案。但是我没时间了,我想看看我是否能让你朝着正确的方向前进。

我相信你正在寻找的是一个数组数组。AFetchedResult将返回一个可选数组,您需要确保它不为零。我compactMap在示例中使用了生成示例可选数组的非零数组,这些数组旨在模拟您从@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
于 2020-09-03T03:22:31.110 回答