Let's assume an app using Core Data with one Item
entity having a name and a date.
How to dynamically set the sortDescriptors
parameter of a @FetchRequest
in a custom View initializer?
The code below triggers an error:
Accessing a SceneStorage value outside of being installed on a View. This will always return the default value.
enum ItemSort: String {
case date
case name
static let `default`: Self = .date
var descriptor: SortDescriptor<Item> {
switch self {
case .date:
return .init(\.date, order: .forward)
case .name:
return .init(\.name, order: .forward)
}
}
}
struct ItemList: View {
@SceneStorage private var sort: ItemSort
@FetchRequest private var items: FetchedResults<Item>
init() {
_sort = .init(wrappedValue: .default, "itemSort")
_items = .init(sortDescriptors: [_sort.wrappedValue.descriptor], animation: .default) // Error: Accessing a SceneStorage value outside of being installed on a View. This will always return the default value.
}
var body: some View {
List(items) { item in
/* ... */
}
}
}
CodePudding user response:
You can try doing it at the top of body like this:
var body: some View {
let _ = items.sortDescriptors = [sort.descriptor]
List(items) { item in
It isn't a state mutation so theoretically it's fine. It might benefit from extracting it out to a func that checks if the current sortDescriptors
already has the correct order and only set it if required.