2017-10-12 3 views
0

테이블의 위치 목록을 표시 할 수 있습니다. 하지만 지금은 현재 위치에 따라 정렬하고 싶습니다.테이블에 사용자에게 가장 가까운 위치 목록 표시

이것은 내 위치를 표시하는 방법입니다 : 내가 https://stackoverflow.com/a/35200027/6362735에서 가져온 내 Location 클래스에서이 거리를 구현하기 위해 노력했다

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 
} 

을하지만 난 옆에 어떻게 무엇을해야하는지 잘 모르겠어요 정렬 해. 현재 위치를 표시

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를 정렬하는 것입니다

여기 내 위치 클래스입니다. 이 2 가지를 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 또는 sorted가 따라 사용할 수있는 기억 자리에 또는 정렬 된 복사본을 만듭니다. CLLocationManager가 작동하는 방법에 대한 자세한 내용은 here을 읽어야합니다.

+0

답장을 보내 주셔서 감사합니다. 하지만 내 앱에서 이걸 어디에 부르는지 정교 할 수 있니? – mninety5

+0

앱 구성 방식에 따라 다릅니다.필터링 동작을 트리거하는 버튼이나 무언가가 있다면, 거기에 넣어야합니다. 당신의 위치가 항상 거리별로 정렬되기를 원하면, 예를 들어 viewDidLoad에서 TableView의 컨트롤러 안에 넣을 수 있습니다. 두 가지 경우에 대한 답변을 업데이트하겠습니다. – jvrmed

+0

내가 매개 변수에 무엇을 넣을 까? 내가 당신의 정렬 기능을 사용할 때, 단지 '매개 변수에 대한 누락 된 인수'가 '호출 중'이라고 말합니다. 그것은'CLLocation'을 기대하고 있습니다. – mninety5

0

left < right에 의해 생성 된 배열을 정렬하기 위해 distance 기능을 사용

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

(단위 테스트) 기능을 증명 :

다음
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을 보시겠습니까? 그것은 당신이 필요로하는 것을해야합니다. 어느 쪽이든, 표준'CLLocation' 객체가 초기화 될 때와 동일한 lat/long 값으로 2DMake를 초기화합니다. – brandonscript