I've been stuck on this for a good couple of days now trying to figure out what the issue is.
I have built a view which lists data which I can put in and save using core data.
My data model looks like so
I can add data to the list and read it all back without any issue, but when I try and filter the fetched results, I get the error that is in the title. The error is about half way down the code.import CoreData
struct CollectionRow: View {
var collectionDate = Date()
let dateFormatter = DateFormatter()
var body: some View {
dateFormatter.dateStyle = .short
dateFormatter.locale = Locale(identifier: "en_GB")
return Text(dateFormatter.string(from: collectionDate))
}
}
struct CollectionList: View {
var hospital = Hospital()
@Environment(\.managedObjectContext) var managedObjectContext
@FetchRequest(
entity: Collection.entity(),
sortDescriptors: [
NSSortDescriptor(keyPath: \Collection.date, ascending: true)
]
) var collections: FetchedResults<Collection>
@State private var collectionName = ""
var body: some View {
NavigationView {
List {
VStack {
ForEach(collections, id: \.self) { collection in //Unable to infer complex closure return type; add explicit type to disambiguate
if self.hospital.id == collection.hospital {
NavigationLink(destination: CollectionRow(collectionDate: Date())){
CollectionRow(collectionDate: Date())
}
}
}
TextField("Test", text: $collectionName)
Button(action: {
let col = Collection(context: self.managedObjectContext)
col.date = Date()
col.id = Int16(self.collections.endIndex + 1)
col.hospital = self.hospital.id
self.hospital.addToHospToCol(col)
do {
try self.managedObjectContext.save()
} catch {
print(error)
}
self.collectionName = ""
}) {
Text("New Collection")
}
}
}
.navigationBarTitle(Text((hospital.name ?? "") + " - " + String(hospital.id)))
}
}
}
EDIT: The official tutorial uses an if statement inside a ForEach, so why can't I?
ForEach(landmarkData) { landmark in
if !self.showFavoritesOnly || landmark.isFavorite {
NavigationLink(destination: LandmarkDetail(landmark: landmark)) {
LandmarkRow(landmark: landmark)
}
}
}
if/else
in SwiftUI can only be used inside @ViewBuilder
closures, hence the ForEach
failing.
More about function builders here.
A simple solution would be to wrap your code like this:
struct ForEachBuilder<Content>: View where Content: View {
private let content: Content
init(@ViewBuilder content: () -> Content) {
self.content = content()
}
var body: some View {
content
}
}
And your ForEach
would become:
ForEach(collections, id: \.self) { collection in
ForEachBuilder {
if self.hospital.id == collection.hospital {
// Your navigation link
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With