搜索外部数据库时ProgressView无法显示的问题排查
问题:搜索外部数据库时ProgressView无法显示
我使用以下视图搜索外部数据库,除ProgressView无法显示外,其他功能均正常。尝试将.overlay修饰符放在.onSubmit之后,仍无法显示。我忽略了什么?这是否是对isSearching的错误用法?
struct SearchDatabaseView: View { @Environment(\.dismiss) private var dismiss @Environment(\.isSearching) private var isSearching: Bool @State private var searchText: String = "" @State private var searchResults: [Record] = [] var body: some View { NavigationStack { List(searchResults, id: \.self) { record in /// display results here } .navigationTitle("Search Database") .toolbar { Button(action: { dismiss() }) { Text("Done") } } .overlay { if isSearching { ProgressView("Searching Database...") } } } .searchable(text: $searchText) .disableAutocorrection(true) .onSubmit(of: .search) { searchDatabase() } } }
解决方案
你对isSearching的理解有误:这个环境变量仅用来标记搜索栏是否处于激活状态(比如用户点击搜索框展开、正在输入内容),而非搜索请求的执行状态。当用户提交搜索(点击搜索按钮/回车)后,搜索栏会自动收起,isSearching会立刻切换为false,导致ProgressView根本没机会展示。
正确的做法是新增独立状态变量追踪搜索加载状态:
- 添加加载状态变量:
@State private var isLoading = false
- 修改
searchDatabase()方法,在请求前后更新加载状态(异步操作中处理,避免阻塞主线程):
private func searchDatabase() { isLoading = true // 替换为你的实际外部数据库请求逻辑 Task { do { searchResults = try await fetchRecords(query: searchText) } catch { // 根据需求处理错误,比如弹窗提示 print("搜索失败:\(error)") } isLoading = false } }
- 将
overlay的判断条件改为isLoading:
.overlay { if isLoading { ProgressView("Searching Database...") } }
修改后的完整代码:
struct SearchDatabaseView: View { @Environment(\.dismiss) private var dismiss @Environment(\.isSearching) private var isSearching: Bool @State private var searchText: String = "" @State private var searchResults: [Record] = [] @State private var isLoading = false // 新增加载状态变量 var body: some View { NavigationStack { List(searchResults, id: \.self) { record in /// display results here } .navigationTitle("Search Database") .toolbar { Button(action: { dismiss() }) { Text("Done") } } .overlay { if isLoading { ProgressView("Searching Database...") } } } .searchable(text: $searchText) .disableAutocorrection(true) .onSubmit(of: .search) { searchDatabase() } } private func searchDatabase() { isLoading = true Task { do { // 替换为你的实际外部数据库请求逻辑 searchResults = try await fetchRecords(query: searchText) } catch { print("搜索失败:\(error)") } isLoading = false } } // 模拟外部数据库请求方法 private func fetchRecords(query: String) async throws -> [Record] { // 这里写你的实际请求代码 try await Task.sleep(nanoseconds: 2_000_000_000) return [] } } // 假设的Record模型 struct Record: Identifiable, Hashable { let id = UUID() // 模型属性 }
内容的提问来源于stack exchange,提问作者koen
相关产品推荐
相关产品推荐

