1

I'm having trouble figuring out how to dynamically update Core Data's FetchRequest's NSSortDescriptor in SwiftUI. I'm not sure if setting it in .onAppear is the correct way which it doesn't as I'm seeing a strange rearranging of my list. I'm using an AppStorage variable to store my sorting then I set the NSSortDescriptor .onAppear, and save when state changes. Also I detect any changes in my Picker selection and apply it to my FetchRequest configuration's sort descriptor like Apple describe's here. If I remove the FetchRequest's animation I don't see the strange rearranging but I also don't get any animations which doesn't look nice. I'm really unsure how to solve this or if I'm even doing this right.

struct ContentView: View {
    @Environment(\.managedObjectContext) private var viewContext
    // Set default sort descriptor as empty because it's set in onAppear
    @FetchRequest(
        sortDescriptors: [],
        animation: .default) // or set to .none
    private var items: FetchedResults<Entity>
    @AppStorage("sortby") var sortby: SortBy = .title
    var body: some View {
        NavigationView {
            List {
                ForEach(items) { item in
                    Text(item.title)
                }
            }
            .toolbar {
                ToolbarItem(placement: .navigationBarLeading) {
                    ForEach(sort.allCases) { sort in
                        Button(sort.title, action: {
                            sortby = sort
                        })
                    }
                }
            }
            // When sort changes set the new value here
            .onChange(of: sortby, perform: { value in
                items.nsSortDescriptors =  //NSSortDescriptor here
            })
            // Set initial sort descriptor here
            .onAppear(perform: {
                items.nsSortDescriptors =  //NSSortDescriptor here
            })
        }
    }
}

FetchRequest's animation is set to default and rearranging.

animation sorting issue

FetchRequest's animation is set to none, it works but then no animations become available when sorting.

sorting no animation

cole
  • 1,039
  • 1
  • 8
  • 35
  • Instead of setting it in onAppear your FetchRequest should have a default sort descriptor set. – Joakim Danielson May 17 '22 at 05:48
  • @JoakimDanielson I’ve set a default and it does the same rearranging. – cole May 17 '22 at 05:51
  • Consider this approach https://stackoverflow.com/a/61632618/12299030. – Asperi May 17 '22 at 06:07
  • @Asperi I understand that yes but that won't resolve my issue. – cole May 17 '22 at 06:12
  • You should set the sort descriptors in an init : as you do , you first have 1st fetch with no sort when the view is created, then a second fetch in onAppear, then a third one on change of sort. The first one can be avoided by setting the default sort with the one from app storage in init() if that is your problem. – Ptit Xav May 17 '22 at 06:39
  • @PtitXav that won't work in init(). Accessing StateObject's object without being installed on a View. – cole May 17 '22 at 07:32
  • @cole I am currently facing the same problem you had. Have you please found a solution? I would be very grateful. Thank you! – parapote Aug 26 '22 at 01:35
  • @parapote I haven’t found a solution, I opted for static. It resets when the app is killed but works. I haven’t spent much more time on dynamic sorting – cole Aug 27 '22 at 15:52

0 Answers0