You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftData获取总记录数及视图分支优化问题咨询

问题与优化请求

需求背景

学习Paul Hudson的SwiftData教程后,希望对原有代码做两处修改:

  • 使用内置的ContentUnavailableView.search展示无搜索结果视图
  • 当SwiftData的Person类初始无记录时,显示带“添加”按钮的自定义ContentUnavailableView

当前实现与疑问

目前通过计算属性private var allPeople: Int获取记录数,结合.onAppear更新personCount来做视图分支判断,但有两个核心疑问:

  1. 是否有更优的获取Person记录数的方式?
  2. 这种基于计数的视图分支是否为合理设计(曾见过用.overlay的方式)?
    另外,需要把ContentView中维护的记录数传递给PeopleView,以便删除记录时更新计数。

当前代码

struct ContentView: View {
    @Environment(\.modelContext) var modelContext
    
    @State private var destPath = NavigationPath()
    @State private var sortOrder = [SortDescriptor(\Person.name)]
    @State private var searchText = ""
    
    // Current "Person" count
    @State private var personCount = 0
    
    // TEST - Finding the total object count for Person and see if I could keep it updated in this view
    private var allPeople: Int {
        let decriptor = FetchDescriptor<Person>(predicate: #Predicate { !$0.name.isEmpty })
        return (try? modelContext.fetchCount(decriptor)) ?? 0
    }
        
    var body: some View {
        NavigationStack(path: $destPath) {
            Group {
                if personCount > 0 {
                    PeopleView(searchString: searchText, weHavePeople: $personCount, sortOrder: sortOrder)
                        .navigationTitle("Face Facts Man: \(personCount)")
                        .toolbar {
                            Menu("Sort", systemImage: "arrow.up.arrow.down") {
                                Picker("Sort", selection: $sortOrder) {
                                    "
                                    "
                                }
                            }
                            
                            Button("Add Person", systemImage: "plus", action: addPerson)
                        }
                        .searchable(text: $searchText, prompt: "Find Some People...")   
                } else {
                    ContentUnavailableView(label: {
                        Label("You Must Know Someone", systemImage: "list.bullet.rectangle.portrait")
                    }, description: {
                        Text("ContentView: Go ahead, add some people! \(personCount)")
                    }, actions: {
                        Button("Add A Person", systemImage: "person.badge.plus", action: addPerson)
                            .buttonStyle(.borderedProminent)
                    })
                }
            }
            .navigationDestination(for: Person.self) { chosenPerson in
                EditPersonView(person: chosenPerson, navPath: $destPath)
            }
            // TEST: Put in to see if the count was updating and assign so that we can branch above in Group
            .onAppear {
                personCount = allPeople
            }
        }
    }
    
    /*
     Creates the new person and inserts it as "blank" into context.  Then change the destPath
     to the correct Person we are going to edit.  It's now binded and auto-saving is now done as
     fields are changed on edit screen.
    */
    func addPerson() {
        let newPerson = Person(name: "", emailAddress: "", details: "")
        modelContext.insert(newPerson)
        destPath.append(newPerson)
    }
}

内容的提问来源于stack exchange,提问作者S. Hatmaker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 10:59:58