如何知道 SwiftUI 视图重绘何时完成

问题描述 投票:0回答:1

我的 MacOS 应用程序使用 SwiftData 和 SwiftUI 来存储和显示食谱。当我向 SwiftData 模型添加新菜谱时,我的菜谱列表会更新。此时,我想通过更改状态变量 (selectedRecipe) 并使用 .onChange 修饰符来操作scrollTo() 命令,以编程方式滚动到新配方。但我相信滚动永远不会发生,因为列表尚未更新。

我已经使用非 SwiftData 模型进行了尝试,效果很好,所以我相当确定 SwiftData 引入了延迟。我的问题是,有没有办法知道列表更新何时完成,此时我可以安全地使用scrollTo()?

这是我的(简化的)代码:

@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
}
swiftui swift-data
1个回答
0
投票

主要原因不是视图在数据插入之前更新。即使在

scrollTo
之前添加延迟也不会滚动。

您传递给

scrollTo
的 ID,即
new
的类型为
UUID?
,但
List
中的视图可能将
UUID
作为其 ID。类型不匹配,因此不会滚动。

使用前应拆开

new

if let new {
    proxy.scrollTo(new, anchor: .top)
}
© www.soinside.com 2019 - 2024. All rights reserved.