如何在 swiftui 中使用 completionHandler 响应?

How to use completionHandler response in swiftui?

在 swiftui 应用程序中,我根据搜索栏检索地址。对于每个地址,我想检索用户位置和地址之间的距离。所以我创建了一个函数(returns 一个字符串),我直接在 swiftui 的文本组件中调用它。但是答案来自completionHandler,我不知道如何在text()中得到这种答案。

函数 return 字符串中的距离:

func getDistance(placeMarkLocation: MKLocalSearchCompletion, currentLocation: CLLocation, completionHandler: @escaping (String) -> ()) {
  let searchRequest = MKLocalSearch.Request(completion: placeMarkLocation)
  let search = MKLocalSearch(request: searchRequest)
  var placeMarkCoordinates: CLLocation = CLLocation(latitude: 0, longitude: 0)
        
  search.start { (response, error) in
    guard let coordinate = response?.mapItems[0].placemark.coordinate else {
      return
    }

    placeMarkCoordinates = CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude)
      
    completionHandler("\(currentLocation.distance(from: placeMarkCoordinates).getDistanceString)")
  }
}
ForEach(locationSearchService.searchResults.indices, id: \.self) { index in
  HStack(spacing: 5) {
    VStack(alignment: .leading, spacing: 2) {
      TextWithAttributedString(attributedString: self.highlightedText(
        text: locationSearchService.searchResults[index].title,
        inRanges: locationSearchService.searchResults[index].titleHighlightRanges,
        size: 20.0
      ) as! NSMutableAttributedString, dynamicHeight: $height)
        .frame(minHeight: height)
        .fixedSize(horizontal: false, vertical: true)                                   
      }
      .frame(minWidth: 0, maxWidth: geometry.size.width)
      .padding(.leading, 15)
      .padding(.top, 10)
      .padding(.bottom, index + 1 == locationSearchService.searchResults.count ? 20 : 10)

      Spacer()
      
      // No work          
      Text("\(self.getDistance(placeMarkLocation: locationSearchService.searchResults[index], currentLocation: CLLocation(latitude: 47.2102877, longitude: -1.5692436)) { value in value })")
        .foregroundColor(Color.gray)
        .padding(.trailing, 15)
        .padding(.top, index == 0 ? 20 : 10)
        .padding(.bottom, index + 1 == locationSearchService.searchResults.count ? 20 : 10)
    }
  }
}       

您可以创建一个将搜索结果 (locationSearchService.searchResults[index]) 作为参数的子视图。其目的是显示计算出的距离。 当这个(每个)子视图出现(onAppear)时,可以执行计算距离的函数(getDistance)。 完成处理程序将更新此子视图的状态。

struct DistanceView: View {
    @State private var distance: String?
    let placeMarkLocation: MKLocalSearchCompletion
    var body: some View {
        Text(distance ?? "getting distance")
            .onAppear {
                getDistance(placeMarkLocation: placeMarkLocation, currentLocation: CLLocation(latitude: 47.2, longitude: -1.5)) { value in
                    distance = value
                }
            }
    }
}