2017-10-12 4 views
0

Ich kann die Liste der Standorte in einer Tabelle anzeigen. Aber jetzt möchte ich es basierend auf dem aktuellen Standort sortieren. DieseZeigt eine Liste der nächstgelegenen Standorte für den Benutzer in einer Tabelle an

ist, wie ich meine Positionen angezeigt:

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 
} 

habe ich versucht, diese Strecke in meiner Location Klasse zu implementieren, die ich von https://stackoverflow.com/a/35200027/6362735 bekam aber ich bin nicht sicher, was ich tun müssen, um nächstes und wie man ordne es.

Hier ist meine Lage Klasse:

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

den aktuellen Standort angezeigt:

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 
} 

Antwort

2

Was müssen Sie jetzt tun, ist LocationManager.shared.locations nach Entfernung zu sortieren und zu Ihrem Standort des Benutzers als Parameter übergeben. Sie können diese zwei in Ihre LocationManager setzen.

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

Nachdem Sie die Orte sortieren, rufen tableView.reloadData() und Ihre Zeilen sollten nach Entfernung werden.

Die Verwendung dieses Codes hängt davon ab, wie Ihre App strukturiert ist.

Wenn Sie eine Taste verwenden zu filtern, können Sie Ihre Standorte innerhalb der Aktion sortieren:

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

Wenn Sie Ihre Daten wollen immer bestellt werden, können Sie es sortieren, wenn Sie erstellen Ihre tableView zum ersten Mal. In Ihrem UIViewController:

let sortedLocations: [Location]() 

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

und dann Sie Ihre dataSource Methode für ändern: Speichern

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 
} 

Auch, dass Sie entweder sort oder sorted je nutzen können, wenn Sie sortieren wollen an Ort und Stelle oder erstellen Sie eine sortierte Kopie. Weitere Informationen zur Funktionsweise des CLLocationManagers finden Sie unter here.

+0

Vielen Dank für Ihre Antwort. Aber könnten Sie näher erläutern, wo ich das in meiner App nennen würde? – mninety5

+0

Es hängt davon ab, wie Ihre App strukturiert ist.Wenn Sie eine Schaltfläche oder etwas haben, das die Filteraktion auslöst, sollten Sie es dort ablegen. Wenn Sie möchten, dass Ihre Standorte immer nach Entfernung sortiert sind, können Sie sie beispielsweise in 'viewDidLoad' in den Controller Ihres TableViews einfügen. Ich werde die Antwort mit beiden Fällen aktualisieren. – jvrmed

+0

Wie lege ich die Parameter fest? Wenn ich Ihre Sortierfunktion verwende, heißt es nur: 'Missing argument for parameter 'to' in call'. Es erwartet eine 'CLLocation'. – mninety5

0

Verwenden Sie Ihre distance Funktion von left < right das resultierende Array zu sortieren:

locations.sorted(by: { $0.distance(to: myLocation) < $1.distance(to: myLocation) }) 

Hier ist ein funktionierendes Beispiel Sie können testen:

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

Proving die Funktion (Unit-Test):

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

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

Vielen Dank für Ihre Antwort. Ich bin ein wenig verwirrt, wie ich "myLocation" anstelle eines fest codierten Standorts als aktuellen Standort verwenden kann? Mein Code zeigt, wie ich den aktuellen Standort erhalte. Aber es ist ein 'CLLocationCoordinate2DMake' und nicht ein' CLLocation', wie es Ihre Methode erfordert. Wie bekomme ich die Daten auf meinem Tisch? – mninety5

+1

Werfen Sie einen Blick auf https://Stackoverflow.com/a/25698536/1214800? es sollte tun, was Sie brauchen. In beiden Fällen initialisieren Sie den 2DMake mit Lat/Long-Werten genauso wie ein Standardobjekt 'CLLocation' initialisiert wird. – brandonscript

Verwandte Themen