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

搜索外部数据库时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根本没机会展示。

正确的做法是新增独立状态变量追踪搜索加载状态:

  1. 添加加载状态变量:
@State private var isLoading = false
  1. 修改searchDatabase()方法,在请求前后更新加载状态(异步操作中处理,避免阻塞主线程):
private func searchDatabase() {
    isLoading = true
    // 替换为你的实际外部数据库请求逻辑
    Task {
        do {
            searchResults = try await fetchRecords(query: searchText)
        } catch {
            // 根据需求处理错误,比如弹窗提示
            print("搜索失败:\(error)")
        }
        isLoading = false
    }
}
  1. 将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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 10:55:50