在 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
]
*/
我可以在 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
]
*/