【问题标题】:How to use completionHandler response in swiftui?如何在swiftui中使用completionHandler响应?
【发布时间】:2021-10-16 03:56:51
【问题描述】:

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

以字符串形式返回距离的函数:

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)
    }
  }
}       

【问题讨论】:

  • 由于ForEach,您的问题会稍微复杂一些,这意味着您需要多次调用getDistance。基本上,您需要为每个项目调用getDistance 并将它们存储在某个地方——也许是由位置ID 键入的Dictionary。然后,在您的ForEach 中,如果Dictionary 中有一个值(即getDistance 已完成并且有一个值要显示),您将只显示Text

标签: swiftui completionhandler


【解决方案1】:

您可以创建一个将搜索结果 (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
                }
            }
    }
}

【讨论】:

  • 我没有想到这种方法,谢谢,它就像一个魅力!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-09
  • 2023-03-06
  • 2021-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多