我有一个SwiftUI
应用,可将数据持久保存在CoreData
中。我想要一个捡拾器
用户可以从一个实体中选择一个项目,然后将该信息存储在
另一个实体作为选择器显示。
我有一个名为Patient的实体,用户在其中添加数据。我有一个实体 名为Clinic的列表,它是用户创建的对象的列表。目的是使用 选择器快速添加信息,而无需为每个重复输入项目 患者记录。
在Swift
中,我通过将UIPicker附加到TextField来做到这一点。很好。我有
在SwiftUI中无法做到等效。我可以创造和填充
选择器数据,我成功将更改保存到“患者”实体,但是我有
在以下情况下,无法将患者诊所数据默认加载到选择器中:
详细视图已加载。
这部分应用等效于主/详细样式。 DetailView是:
struct DetailView: View {
@Environment(\.managedObjectContext) var managedObjectContext
@Environment(\.presentationMode) var presentationMode
@FetchRequest(fetchRequest: Clinic.getAllClinics()) var clinics: FetchedResults<Clinic>
@State private var selectClinicItem: Int = 0
var patient: Patient
@State private var updatedFirstName: String = "No First Name"
@State private var updatedLastName: String = "No Last Name"
@State private var updatedClinic: String = "Clinic Not Chosen"
@State private var chosenClinicUUID: UUID = UUID()
var body: some View {
ScrollView {
Group {//top group
VStack {
MyDataCell(tfData: $updatedFirstName, passedInLabel: "First Name", patient: patient, patientAttribute: patient.firstName ?? "No First")
}//Top VStack - 8 views
}//top Group
Group {//second group
Form {
Picker(selection: self.$chosenClinicUUID, label: Text("Choose Clinic")) {
ForEach(clinics) { c in
Text("\(c.name ?? "no name")")
}
}
.frame(width:320, height: 30)
}//Form
.frame(width:350, height: 200)
.clipShape(RoundedRectangle(cornerRadius: 12))
.overlay(RoundedRectangle(cornerRadius: 12)
.stroke(Color.gray, lineWidth: 2))
.padding(.leading, 12)
.padding(.top, 20)
.padding(.bottom, 20)
}//second Group
}//scroll or top level Form
.modifier(AdaptsToSoftwareKeyboard())
.navigationBarTitle("View and Edit", displayMode: .inline)
.navigationBarItems(trailing: Button(action: {
self.patient.firstName = self.updatedFirstName
self.patient.lastName = self.updatedLastName
self.patient.clinicName = self.updatedClinic
self.patient.clinicID = self.chosenClinicUUID
let n = self.clinics.filter { $0.id == self.patient.clinicID }
if n.count > 0 {
self.patient.clinicName = n[0].name
}
do {
try self.managedObjectContext.save()
} catch {
print(error)
}
self.updatedFirstName = ""
self.updatedLastName = ""
self.updatedClinic = ""
self.presentationMode.wrappedValue.dismiss()
}) {
Text("Save")
})
}//body
}
患者类,供参考:
public class Patient : NSManagedObject, Identifiable {
@NSManaged public var id: UUID
@NSManaged public var firstName: String?
@NSManaged public var lastName: String?
@NSManaged public var clinicName: String?
@NSManaged public var clinicID: UUID
}
extension Patient {
static func getAllPatients() -> NSFetchRequest<Patient> {
let request: NSFetchRequest<Patient> = Patient.fetchRequest() as! NSFetchRequest<Patient>
let sortDescriptor = NSSortDescriptor(key: "lastName", ascending: true)
request.sortDescriptors = [sortDescriptor]
return request
}
}
诊所课程:
public class Clinic : NSManagedObject, Identifiable {
@NSManaged public var id: UUID
@NSManaged public var name: String?
@NSManaged public var comment: String?
@NSManaged public var isShown: Bool
}
extension Clinic {
static func getAllClinics() -> NSFetchRequest<Clinic> {
let request: NSFetchRequest<Clinic> = Clinic.fetchRequest() as! NSFetchRequest<Clinic>
let sortDescriptor = NSSortDescriptor(key: "name", ascending: true)
request.sortDescriptors = [sortDescriptor]
return request
}
}
任何指导将不胜感激。 Xcode版本11.2.1(11B500)
答案 0 :(得分:1)
这就是我所做的,一个Icon的虚拟实例
sData[2].status
...在我的代码后面,我能够添加关系
{
"from": 0,
"size": 5,
"_source": ["sData.status"],
"query": {
"bool": {
"must":[
{
"wildcard": {
"server": "*ABC2501*"
}
},
{
"wildcard": {
"sData[2].status": "*Finish*"
}
}
]
}
},
"sort": [
{ "requestDate": {"order": "desc"}}
]
}
您可以的话
@FetchRequest(
entity: Icon.entity(),
sortDescriptors: []
) var coreDataIcon: FetchedResults<Icon>
@State private var oneCoreDataIconIndex: Int = 0
var body: some View {
Form {
Picker("Select Icon", selection: $oneCoreDataIconIndex) {
ForEach (0..<coreDataIcon.count) {
Image(systemName: self.coreDataIcon[$0].wrappedIcon)
.tag($0)
.font(.title)
}//ForEach
}//Picker
}//Form
...和
oneAccount.icon = self.coreDataIcon[self.oneCoreDataIconIndex]
稍后在您的代码中
@State private var chosenClinicIndex: Int = 0
这还会显示您选择之前的初始诊所
像我的答案 1 :(得分:0)
尝试使用Int
(与数组结合使用)而不是实际的UUID
作为选择变量。检出this。
答案 2 :(得分:0)
通过在初始化期间手动设置选定的索引来解决该问题。似乎是一种奇怪的方式。
struct MyView: View {
...
@ObservedObject var model = VideoDetailsModel()
@State var selectedCategoryIndex : Int = -1
// Init with initial model
init(onDismiss: @escaping (VideoDetails?) -> ()) {
self.onDismiss = onDismiss
}
// Init with existing model
init(model: VideoDetailsViewModel, onDismiss: @escaping (VideoDetails?) -> ()) {
self.model = model
self.onDismiss = onDismiss
let selectedIndex = self.model.categories.categories.firstIndex(where: {
return $0 == self.model.videoModel?.categories[0]
}) ?? -1
// Force the set state here since initialisation is optional
_selectedCategoryIndex = .init(initialValue: selectedIndex)
}
var body: some View {
...
Picker(selection: $selectedCategoryIndex , label: Text("Category")) {
ForEach(0..<self.model.categories.categories.count, id: \.self) { index in
Text(self.model.categories.categories[index])
}
}
...
}