Core data SwiftUI Picker多个错误、核心数据、布局

Core data SwiftUI Picker多个错误、核心数据、布局,core-data,swiftui,Core Data,Swiftui,我一直在努力让表单布局中的多个选择器在SwiftUI中工作 作为测试,我创建了一个简单的视图,其中包含一些文本标签、一些文本字段和 两个采摘者。它是一个核心数据应用程序。通过首先创建 数组。第二个直接从核心数据填充。似乎没有 功能或错误上的差异 该功能似乎正在运行,但我发现这些错误看起来像是真的 问题单击选择器后,我会毫无疑问地切换到选择器列表。 单击列表项后,选择器列表将被取消,我将返回ContentView 选择选择器中列出的相应选项。然而,在这两种情况下,我都得到了 这些错误: 一,。 F

我一直在努力让表单布局中的多个选择器在SwiftUI中工作

作为测试,我创建了一个简单的视图,其中包含一些文本标签、一些文本字段和 两个采摘者。它是一个核心数据应用程序。通过首先创建 数组。第二个直接从核心数据填充。似乎没有 功能或错误上的差异

该功能似乎正在运行,但我发现这些错误看起来像是真的 问题单击选择器后,我会毫无疑问地切换到选择器列表。 单击列表项后,选择器列表将被取消,我将返回ContentView 选择选择器中列出的相应选项。然而,在这两种情况下,我都得到了 这些错误:

一,。 ForEach,Int,Text>count(10)!=其初始计数(1)
ForEach(uquo:content:)
只能用于常量数据。相反,将数据与可识别的一致,或者使用ForEach(uu:id:content:)并提供明确的
id

二,。 [TableView]仅警告一次:UITableView被告知布局其可见单元格和其他内容,而不在视图层次结构中(尚未将表视图或其中一个超级视图添加到窗口)。这可能会导致错误,因为在没有准确信息的情况下,强制加载表视图中的视图并执行布局…以及更冗长的语句

这是主要观点:

struct ContentView: View {

    @Environment(\.managedObjectContext) var managedObjectContext
    @FetchRequest(fetchRequest: Clinic.getAllClinics()) var clinics: FetchedResults<Clinic>

    @State var nameArray = Clinic.makeClinicNameArray()

    @State private var selectArrayItem = 0
    @State private var selectCoreDataItem = 0
    @State private var tfOne = "TextField One"
    @State private var tfTwo = "TextField Two"
    @State private var tfThree = "TextField Three"
    @State private var tfFour = "TextField Four"

    var body: some View {
        NavigationView {

            Form {

            //I have include groups because in the real app I have many more than
            //ten views in the parent view
                Group {
                    TextField("enter a value for tfOne", text: $tfOne).foregroundColor(.blue)
                }

                Section(header: Text("From Generated Array:"), footer: Text("Section End")) {
                    Picker(selection: $selectArrayItem, label: Text("Choose Array Clinic")) {
                        ForEach(0 ..< nameArray.count) {
                            Text(self.nameArray[$0])
                        }
                    }
                    .foregroundColor(.red)

                    Picker(selection: $selectCoreDataItem, label: Text("Choose Core Data Clinic")) {
                        ForEach(0 ..< clinics.count) {
                            Text("\(self.clinics[$0].name ?? "Nameless")")
                        }
                    }.foregroundColor(.orange)

                    Text("$selectArrayItem is \(selectArrayItem)")
                    Text("item name is \(self.nameArray[selectArrayItem])")
                }//section 1

                Group {
                    TextField("enter a value for tfTwo", text: $tfTwo).foregroundColor(.blue)
                    TextField("enter a value for tfThree", text: $tfThree).foregroundColor(.blue)
                }

                Section(header: Text("From Core Data:"), footer: Text("Section End")) {
                    Text("$selectCoreDataItem is \(selectCoreDataItem)")
                    Text("item name is \(self.clinics[selectCoreDataItem].name ?? "Nameless")")
                }//section two

                TextField("enter a value for tfFour", text: $tfFour).foregroundColor(.blue)

            }//Form
            .navigationBarTitle(Text("Spinners"))

        }//nav view
    }
} 
非常简单的选项卡栏: 结构选项卡栏:视图{

@Environment(\.managedObjectContext) var managedObjectContext
@State private var selectionValue = 1

var body: some View {
    TabView(selection : $selectionValue) {
        ContentView().tabItem ({
            Image(systemName: "house")
            Text("Home")
        })
        .tag(1)

        Utilities().tabItem ({
            Image(systemName: "hammer")
            Text("Utilities")
        })
        .tag(2)

        StartView().tabItem ({
            Image(systemName: "forward.fill")
            Text("Start")
        })
        .tag(3)
    }
}
}

对#1的回答几乎可以肯定,您需要使用带有
id
参数的
ForEach
初始值设定项,并且
选择的类型必须与
id
的类型匹配

比如说

@State private var selectArrayItem = 0

...

Picker(selection: $selectArrayItem, label: Text("Choose Array Clinic")) {
    ForEach(0 ..< nameArray.count, id: \.self) {
        Text(self.nameArray[$0])
    }
}
将起作用,因为
selectName
id
都是
String

至于#2,我几乎可以肯定这是SwiftUI中的一个bug。当我点击“Choose Array Clinic”行时,我看到上面提到的错误消息被打印出来,并显示诊所列表。您会注意到,在将选择器视图推到导航堆栈上之后,表行在出现后不久会略微跳跃


错误消息和视觉跳转让我推测SwiftUI正在尝试在导航堆栈的技术部分之前布置行,导航堆栈打印错误,然后一旦添加错误,视图行偏移将重新计算,从而导致跳转。所有这些都不在您的控制之下,并且使用最简单的
表单
/
选择器
演示代码即可实现。最好的办法是把它当作一只虫子,暂时忍受它。除了视觉跳转,目前似乎没有任何功能问题。

错误1解释了两种解决方案,您尝试过吗?是的。没有快乐。如果我特别声明id:则选择器不会返回所选项目。看起来很奇怪。无论如何,ManagedObject是可识别的。我明白了。我不明白ForEach初始值设定项和选择器选择必须是同一类型。当我尝试id时:我使用的是myID属性,它是UUID。使阵列和核心数据版本都具有id:\。自行修复此问题,现在两者都会生成正确的结果,而不会出现上面的错误号1。你对错误2-TableView布局有什么想法吗?我的核心数据实现非常简单,但我将编辑问题并添加它。我将此问题标记为已回答,因为错误1更为重要。如果有人能帮我的话,我还是想听听关于问题2的评论。我会在回到我的电脑后再看一看。我在最后补充了一点关于第二个错误的内容。TL;DR可能是一个SwiftUI bug,明白了。我会报告的。谢谢
@Environment(\.managedObjectContext) var managedObjectContext
@State private var selectionValue = 1

var body: some View {
    TabView(selection : $selectionValue) {
        ContentView().tabItem ({
            Image(systemName: "house")
            Text("Home")
        })
        .tag(1)

        Utilities().tabItem ({
            Image(systemName: "hammer")
            Text("Utilities")
        })
        .tag(2)

        StartView().tabItem ({
            Image(systemName: "forward.fill")
            Text("Start")
        })
        .tag(3)
    }
}
@State private var selectArrayItem = 0

...

Picker(selection: $selectArrayItem, label: Text("Choose Array Clinic")) {
    ForEach(0 ..< nameArray.count, id: \.self) {
        Text(self.nameArray[$0])
    }
}
@State private var selectName = "" 

...

Picker(selection: $selectArrayItem, label: Text("Choose Array Clinic")) {
    ForEach(nameArray, id: \.self) {
        Text($0)
    }
}