在 table 上显示离用户最近的位置列表

Display a list of the closest locations to the user on a table

我可以在 table 上显示位置列表。但是现在我想根据当前位置排序。

这是我显示位置的方式:

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

    let location = LocationManager.shared.locations[indexPath.row]
    cell.textLabel?.text = location.name
    return cell
}

我已经尝试在我从 获得的 Location class 中实现这个距离,但我不确定下一步需要做什么以及如何对其进行排序.

这是我的位置 class:

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

显示当前位置:

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)

    self.mapView.showsUserLocation = true
}

您现在需要做的是 LocationManager.shared.locations 按距离排序,并将您的用户位置作为参数传递。你可以把这两个放在你的 LocationManager.

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

func sortLocationsInPlace(userLocation: CLLocation) {
    locations.sort { (l1, l2) -> Bool in
        return l1.distance(to: userLocation) < l2.distance(to: userLocation)
    }
}

对位置进行排序后,调用 tableView.reloadData(),您的行应按距离排序。

在何处使用此代码取决于您的应用程序的结构。

如果您使用按钮进行筛选,您可以在操作中对您的位置进行排序:

@IBAction func orderByDistance() {
    sortLocationsInPlace(userLocation: yourUsersLocation)
    tableView.reloadData()
}

如果您希望数据始终有序,您可以在首次创建 tableView 时对其进行排序。在你的 UIViewController:

里面
let sortedLocations: [Location]()

override func viewDidLoad() {
    sortedLocations = getSortedLocations(userLocation: yourUsersLocation)
}

然后你可以改变你的dataSource方法:

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
}

,请记住您可以使用 sort or sorted depending if you want to sort in place or create a sorted copy. For more information about how the CLLocationManager works you should read here

使用 distance 函数按 left < right:

对结果数组进行排序
locations.sorted(by: { [=10=].distance(to: myLocation) < .distance(to: myLocation) } )

这是一个您可以用来测试的工作示例:

import Foundation
import CoreLocation

struct Location {

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

    init(lat: Double, long: Double) {
        self.latitude = lat
        self.longitude = long
    }

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

let locations: [Location] = [
    Location(lat: 61.98573, long: 27.57300),
    Location(lat: -62.98404, long: 62.81190),
    Location(lat: -3.18446, long: 107.07900)]

let myLocation = CLLocation(latitude: 73.30051, longitude: -141.88647)

let locationsClosestToMe = locations.sorted(by: { [=11=].distance(to: myLocation) < .distance(to: myLocation) } )

证明功能(单元测试):

print(locationsClosestToMe.map { [=12=].distance(to: myLocation) } )

/*
[
  4970593.6601553941, 
  11003159.607318919, 
  18486409.053517241
]
*/