SwiftData获取总记录数及视图分支优化问题咨询
问题与优化请求
需求背景
学习Paul Hudson的SwiftData教程后,希望对原有代码做两处修改:
- 使用内置的
ContentUnavailableView.search展示无搜索结果视图 - 当SwiftData的
Person类初始无记录时,显示带“添加”按钮的自定义ContentUnavailableView
当前实现与疑问
目前通过计算属性private var allPeople: Int获取记录数,结合.onAppear更新personCount来做视图分支判断,但有两个核心疑问:
- 是否有更优的获取
Person记录数的方式? - 这种基于计数的视图分支是否为合理设计(曾见过用
.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
相关产品推荐
相关产品推荐

