【发布时间】:2023-01-26 19:51:04
【问题描述】:
我在 Swift 中创建了一个视图(称为AddressInputView),它应该执行以下操作:
- 从用户输入中获取地址
- 当用户点击提交时,启动 ProgressView 动画并将地址发送到后端
- 调用返回后,切换到 ResultView 并显示结果
我的问题是,一旦用户点击提交,视图就会立即切换到 ResultView,而无需等待 API 调用返回。因此,ProgressView 动画仅在一瞬间可见。
这是我的代码:
地址输入视图
struct AddressInputView: View { @State var buttonSelected = false @State var radius = 10_000 // In meters @State var isLoading = false @State private var address: String = "" @State private var results: [Result] = [] func onSubmit() { if !address.isEmpty { fetch() } } func fetch() { results.removeAll() isLoading = true let backendUrl = Bundle.main.object(forInfoDictionaryKey: "BACKEND_URL") as? String ?? "" let escapedAddress = address.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) ?? "" let params = "address=\(escapedAddress)&radius=\(radius)" let fullUrl = "\(backendUrl)/results?\(params)" var request = URLRequest(url: URL(string: fullUrl)!) request.httpMethod = "GET" let session = URLSession.shared let task = session.dataTask(with: request, completionHandler: { data, _, _ in if data != nil { do { let serviceResponse = try JSONDecoder().decode(ResultsServiceResponse.self, from: data!) self.results = serviceResponse.results } catch let jsonError as NSError { print("JSON decode failed: ", String(describing: jsonError)) } } isLoading = false }) buttonSelected = true task.resume() } var body: some View { NavigationStack { if isLoading { ProgressView() } else { VStack { TextField( "", text: $address, prompt: Text("Search address").foregroundColor(.gray) ) .onSubmit { onSubmit() } Button(action: onSubmit) { Text("Submit") } .navigationDestination( isPresented: $buttonSelected, destination: { ResultView( address: $address, results: $results ) } ) } } } } }因此,我尝试在
session.dataTask的完成处理程序中将buttonSelected = true移动到isLoading = false旁边,但如果我这样做,将不会显示 ResultView。难道不能从completionHandler内部更新状态吗?如果是,为什么会这样,解决方法是什么?主要问题:我如何更改上面的代码,以便在 API 调用完成之前不显示 ResultView? (虽然 API 调用尚未完成,但我希望显示 ProgressView)。
【问题讨论】: