2017-10-12 139 views
0

我可以在表格上顯示位置列表。但現在我想根據當前位置對其進行排序。在表格上顯示與用戶最近的位置列表

這是我怎麼顯示我的位置:

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類,我從https://stackoverflow.com/a/35200027/6362735得到這個距離,但我不知道我需要什麼未來,以及如何做把它分類。

這裏是我的位置類:

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 
} 

回答

2

你現在需要做的是通過距離,通過你的用戶的位置作爲參數排序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 
} 

此外,請記住,您可以使用sortsorted取決於如果你想排序到位或創建一個分類副本。有關CLLocationManager如何工作的更多信息,請閱讀here

+0

感謝您的回覆。但是,你能詳細說明我的應用程序在哪裏調用? – mninety5

+0

這取決於您的應用程序的結構。如果你有一個按鈕或什麼東西觸發了過濾操作,你應該把它放在那裏。如果您希望您的位置始終按距離排序,則可以將其放置在TableView的控制器中,例如「viewDidLoad」。我會在兩種情況下更新答案。 – jvrmed

+0

但是我在參數中加入了什麼?當我使用你的排序功能時,它只是說:'參數'缺少參數'調用'。它期待一個'CLLocation'。 – mninety5

0

使用您distance功能通過left < right所得到的數組進行排序:

locations.sorted(by: { $0.distance(to: myLocation) < $1.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: { $0.distance(to: myLocation) < $1.distance(to: myLocation) }) 

證明功能(單元測試):

print(locationsClosestToMe.map { $0.distance(to: myLocation) }) 

/* 
[ 
    4970593.6601553941, 
    11003159.607318919, 
    18486409.053517241 
] 
*/ 
+0

感謝您的回覆。我有點困惑,我如何使用'myLocation'作爲當前位置而不是硬編碼位置?我的代碼顯示了我如何獲取當前位置。但它是一個'CLLocationCoordinate2DMake',而不是像你的方法所要求的'CLLocation'。我怎樣才能得到它在我的桌子上顯示的數據? – mninety5

+1

看看https://stackoverflow.com/a/25698536/1214800?它應該做你需要的。無論採用哪種方式,您都要使用緯度/長度值初始化2DMake,這與標準CLLocation對象的初始化相同。 – brandonscript