My MacOS app uses SwiftData and SwiftUI to store and display recipes. When I add a new recipe to my SwiftData model, my List of recipes updates. At this point I want to programatically scroll to the new recipe by changing a State variable (selectedRecipe) and using the .onChange modifier to action a scrollTo() command. But the scroll never happens, I believe because the List has not yet been updated.
I’ve tried this using a non-SwiftData model and it works fine, so I’m fairly sure that SwiftData has introduced a delay. My question is, is there some way to know when the List update is complete, at which point I can safely use scrollTo()?
Here’s my (simplified) code:
@Environment(.modelContext) var modelContext
var recipes: [Recipe]
@State private var selectedRecipe: UUID?
var body: some View {
NavigationSplitView {
VStack {
ScrollViewReader { proxy in
Listself.recipies, id: .id, selection: $selectedRecipe) { recipe in
RecipeCellView(recipe: recipe)
}
.focusable()
.onAppear() {
if recipes.isEmpty == false {
self.selectedRecipe = recipes[0].id
}
}
.onChange(of: selectedRecipe) { (old, new) in
proxy.scrollTo(new, anchor: .top)
}
}
HStack {
Button { self.addRecipe()
} label: { Text("Add Recipe") }
}
}
} detail: {
if let selectedRecipe = self.selectedRecipe {
let recipe = self.searchResults.first {
$0.id == selectedRecipe }
if let toDisplay = recipe {
RecipeTabView(recipe: toDisplay)
}
}
}
}
func addRecipe() {
let myRecipe = Recipe()
modelContext.insert(myRecipe)
self.selectedRecipe = myRecipe.id
}