I have a main screen with an @FetchRequest
that returns a FetchResult<Item>
. In that main screen I have a list of all of the items with navigation links that, when selected, pass an Item
to an ItemDetail
view. In this ItemDetail
view, item is marked with @ObservedObject
. A subview of ItemDetail
is ItemPropertiesView
which lists all of the item's properties. I pass the item properties directly to @Binding
properties of ItemPropertiesView
using $item.{insert property here}
. In ItemPropertiesView, there's several LineItem
where I pass the property using $ once again to an @Binding
property called "value" which is passed into a text field, that can ultimately be changed.
My goal is to be able to edit this text field and once you're done editing, to be able to save these changes to my core data store.
Since this has been a little hard to read, here is a code recreation:
struct MainScreen: View {
@FetchRequest(entity: Item.entity(), sortDescriptors: [NSSortDescriptor(key: "itemName", ascending: true)]) var items: FetchedResults<Item>
var body: some View {
NavigationView {
List {
ForEach(items, id: \.self) { (item: Item) in
NavigationLink(destination: ItemDetail(item: item)) {
Text(item.itemName ?? "Unknown Item Name")
}
} // ForEach
}
}
} // body
} // MainScreen
struct ItemDetail: View {
@ObservedObject var item: Item
var body: some View {
ItemPropertiesView(itemCost: $item.itemCost)
}
}
struct ItemPropertiesView: View {
@Binding var itemCost: String?
var body: some View {
LineItem(identifier: "Item Cost", value: $itemCost)
}
}
struct LineItem: View {
let identifier: String
@Binding var value: String
var body: some View {
HStack {
Text(identifier).bold() + Text(": ")
TextField("Enter value",text: $value)
}
}
}
I am getting an error in ItemDetail: "The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions"
This is on the only error I'm getting. I'm new to SwiftUI, so all feedback is appreciated.
Just by code reading I assume the problem is in optional property in ItemPropertiesView
, just remove it
struct ItemPropertiesView: View {
@Binding var itemCost: String // << here !!
// .. other code
and update parent to have bridge to CoreData model optional property
struct ItemDetail: View {
@ObservedObject var item: Item
var body: some View {
let binding = Binding(
get: { self.item.itemCost ?? "" },
set: { self.item.itemCost = $0 }
)
return ItemPropertiesView(itemCost: binding)
}
}