Reputation: 161
I want to change the sortDescriptor with a button.
But if I change the variables "sorting" and "sortOrder" to @State variables I get an Error.
The error-message is: Variable 'self.fetchRequest' used before being initialized
@Environment(\.managedObjectContext) private var viewContext
@State var sorting: KeyPath = \Log.diveNr
@State var sortOrder: SortOrder = .forward
private var fetchRequest: FetchRequest<Log>
private var logs: FetchedResults<Log> {
fetchRequest.wrappedValue
}
init() {
fetchRequest = FetchRequest(sortDescriptors: [SortDescriptor(sorting, order: sortOrder)])
}
Can someone help me to resolve this?
SOLUTION:
@FetchRequest(sortDescriptors: [SortDescriptor(\.diveNr, order: .forward)])
var logs: FetchedResults<Log>
var body: some View {
NavigationStack {
List{
if logs.count == 0 {
Text("no Logs found")
}
Button("change order") {
logs.sortDescriptors = [SortDescriptor(\.diveNr, order: .reverse)]
}
ForEach(logs){log in
NavigationLink(destination: DiveLogDetailView(diveNo: 1, diveSite: "Vela Garska")) {
DiveLogListObject(log: log)
}
}
.onDelete(perform: deleteLog)
}
}
Upvotes: 1
Views: 590
Reputation: 30549
You have to set it in body
. Unfortunately @FetchRequest
is either badly designed or badly documented.
func updateSort() {
logs.sortDescriptors = [SortDescriptor(\.diveNr, order: sortOrder)]
}
var body: some View {
let _ = updateSort()
NavigationStack {
Upvotes: 0
Reputation: 385500
Because of the use of @State
, both sorting
and sortOrder
are computed properties. You cannot use a computed property in init
until all stored properties have been initialized. (Otherwise, the computed property's getter might let the not-fully-initialized self
escape.)
So use the underlying stored properties instead:
init() {
let descriptor = SortDescriptor(
_sorting.wrappedValue,
order: _sortOrder.wrappedValue
)
fetchRequest = FetchRequest(sortDescriptors: [descriptor])
}
Upvotes: 1