使用mapKit Swift(英里/公里)显示用户的距离

时间:2017-10-16 00:34:04

标签: ios swift cllocationdistance

我一直试图在tableView上显示距离,但我无法让它发生。这个问题来自这个问题:CLLocationDistance conversion。我检查了距离。在我的Location课程中使用此功能:

// Get distance
func distance(to location: CLLocation) -> CLLocationDistance {
    return location.distance(from: self.location)
}

我如何获得用户当前位置:

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    let location = locations[0]

    let span:MKCoordinateSpan = MKCoordinateSpanMake(0.01, 0.01)
    let myLocation:CLLocationCoordinate2D = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
    let region:MKCoordinateRegion = MKCoordinateRegionMake(myLocation, span)
    mapView.setRegion(region, animated: true)

    // Add a lastUserLocation to LocationManager and update it every time that the delegate receives a new location
    LocationManager.shared.lastUserLocation = locations.last
    LocationManager.shared.sortLocationsInPlace()

    self.mapView.showsUserLocation = true

}

LocationManager中的排序功能:

func getSortedLocations(userLocation: CLLocation) -> [Location] {
        return locations.sorted { (l1, l2) -> Bool in
            return l1.distance(to: userLocation) < l2.distance(to: userLocation)
        }
    }

func sortLocationsInPlace() {
    if let validLocation = lastUserLocation {
        locations.sort { (l1, l2) -> Bool in
            return l1.distance(to: validLocation) < l2.distance(to: validLocation)
        } 
    }
}

cellForRowAt:

var sortedLocations = [Location]()

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "locationCell", for: indexPath)


    let location = sortedLocations[indexPath.row]

    cell.textLabel?.text = location.name
    return cell
}

更新

内部Location类:

class Location {

    var name: String
    var latitude: Double
    var longitude: Double
    var location:CLLocation {
        return CLLocation(latitude: latitude, longitude: longitude)
    }

    init?(json: JSON) {

        guard let name = json["name"] as? String, let latitude = json["latitude"] as? Double, let longitude = json["longitude"] as? Double else { return nil }
        self.name = name
        self.latitude = latitude
        self.longitude = longitude
    }

    func distance(to location: CLLocation) -> CLLocationDistance {
        return location.distance(from: self.location)
    }
}

1 个答案:

答案 0 :(得分:2)

考虑到你的代码,我做了一些假设:

  1. 您的sortedLocations数组具有从 JSON 或其他内容中提取的不同位置。
  2. 在加载数据之前,您可以在某处调用startUpdatingLocation()或类似内容。
  3. 您在didUpdateLocations
  4. 接收更新
  5. 您的LocationManager会将所有位置的有序副本保存在名为locations的变量中,即您在didUpdateLocations内订购的变量。
  6. 考虑,我了解您要做的是根据参考位置显示您订购的sortedLocations

    缺少的是在收到用户位置后更新UITableView数据。您有两个主要选择:

    1. 仅在UITableView检索到您的第一个用户位置后才加载didUpdateLocations
    2. 要在获得新位置后强制UITableView更新,请致电tableView.reloadData()内的didUpdateLocations。每次收到位置更新时,都会重新绘制列表,并按位置对其进行排序。
    3. ,在任何这种情况下,您需要替换cellForRow文字以显示您的距离,而不是location.name

      // Distance in meters
      cell.textLabel?.text = String(location.distance(to: LocationManager.shared.lastUserLocation!))
      
      // Distance in miles
      cell.textLabel?.text = String(location.distance(to: LocationManager.shared.lastUserLocation!)*0.00062137)
      

      更新您的didUpdateLocations

      func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
          if let location = locations.last {
      
              let span:MKCoordinateSpan = MKCoordinateSpanMake(0.01, 0.01)
              let myLocation:CLLocationCoordinate2D = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
              let region:MKCoordinateRegion = MKCoordinateRegionMake(myLocation, span)
              mapView.setRegion(region, animated: true)
      
              // Add a lastUserLocation to LocationManager and update it every time that the delegate receives a new location
              LocationManager.shared.lastUserLocation = location
              LocationManager.shared.sortLocationsInPlace()
      
              sortedLocations = LocationManager.shared.locations
              tableView.reloadData()
      
              self.mapView.showsUserLocation = true
          }
      }
      

      使用您当前的代码,您将所有距离与self.location变量进行比较,而该变量显然未在任何地方进行初始化。