【问题标题】:Choosing CoreData Entities from form picker从表单选择器中选择 CoreData 实体
【发布时间】:2021-11-25 22:48:21
【问题描述】:

我有以下代码:

import SwiftUI

struct LearnView: View {
    
    @State private var selectedLanguage: Language?
    @State private var selectedCategory: SubCategory?
    @State private var selectedDate = Date()
     
    @Environment(\.managedObjectContext) private var viewContext
    @FetchRequest(entity: Language.entity(), sortDescriptors: []) var languages: FetchedResults<Language>
    @FetchRequest(entity: SubCategory.entity(), sortDescriptors: []) var subCategories: FetchedResults<SubCategory>
    
    var body: some View {
        NavigationView {
            ZStack {
                Form {
                    Section("Learning Schedule") {
                        Picker("Please choose a language", selection: $selectedLanguage) {
                            ForEach(languages, id: \.self) {
                                Text($0.name ?? "Unknown")
                            }
                        }
                        Text("You selected: \(selectedLanguage?.name ?? "Unknown")")
                    }
                }
            }
        }
    }
}

我可以点击表单行,然后看到来自 CoreData 'languages' 实体的语言列表。但是,当我在导航到的视图中点击选择器中的一种语言时,它不会对它打上复选标记,而是根据我的选择返回表单屏幕。它只是在“您选择:”文本字段中显示“未知”。

语言和子类别实体:

【问题讨论】:

  • 没有足够的代码来重现这一点(例如查看语言和子类别),这有点像猜谜游戏。我的猜测是Picker 可能很难匹配id 和选择参数。实体是否具有可以使用而不是 .self 的显式 ID?你能用.id()将它们添加到Text吗?
  • @jnpdx 我认为实体没有明确的 ID,查看 CoreData 实体条目(我已在添加的屏幕截图中显示。
  • 所有实体(NSManagedObject 子类)都有一个来自其超类的 ID,名为 objectID,因此您可以使用 tag($0.objectID) 标记您的对象,但从我的测试来看,这没有帮助。
  • @Joakim Danielson 试过了,但没什么区别。

标签: swift core-data swiftui picker


【解决方案1】:

正如您所写的那样,您与选择器和 FetchResult 的数组类型不匹配。查看 cmets

import SwiftUI

@available(iOS 15.0, *)
struct LearnView: View {
    //This is optional Language
    @State private var selectedLanguage: Language?
    //I commented out variables that are not part of the reproducible body provided
    //@State private var selectedCategory: SubCategory?
    //@State private var selectedDate = Date()
    
    @Environment(\.managedObjectContext) private var viewContext
     //This is FetchedResults<Language>
    @FetchRequest(entity: Language.entity(), sortDescriptors: []) var languages: FetchedResults<Language>
    // @FetchRequest(entity: SubCategory.entity(), sortDescriptors: []) var subCategories: FetchedResults<SubCategory>
    
    var body: some View {
        NavigationView {
            ZStack {
                Form {
                    Section("Learning Schedule") {
                        Picker("Please choose a language", selection: $selectedLanguage) {
                            //Map is needed for a plain array of languages
                            //ForEach(languages.map{$0}, id: \.self) { language in
                            //This version works too
                            //The point is to go from FetchedResults<Language> to [Language]
                            ForEach(Array(languages), id: \.self) { language in
                                
                                Text(language.name ?? "Unknown")
                                //The casting is necessary to make it an optional since your @State is an optional
                                    .tag(language as? Language)
                            }
                        }
                        Text("You selected: \(selectedLanguage?.name ?? "Unknown")")
                    }
                }
            }
        }
    }
}

@available(iOS 15.0, *)
struct LearnView_Previews: PreviewProvider {
    static var previews: some View {
        LearnView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
    }
}

【讨论】:

    猜你喜欢
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    • 2013-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-08
    相关资源
    最近更新 更多