【问题标题】:TableView sort by distance from current location (parsing locations from JSON)TableView 按与当前位置的距离排序(从 JSON 中解析位置)
【发布时间】:2018-01-19 12:27:06
【问题描述】:

在 xCode 中,我尝试对 TableView 中的对象进行排序,以便它们按照与用户的接近程度排列。我看到有人问过这个问题,但我似乎无法弄清楚如何在我的项目中实现它,因为我正在通过 JSON 文件解析位置。

我需要做什么来计算用户位置和每个位置对象的位置之间的距离?然后如何按升序对 TableView 中的对象进行排序?

这是 Location.swift 模型:

import Foundation
import MapKit
import CoreLocation

var currentLocation:CLLocation?

class Location: NSObject {
    var id: String = ""
    var name: String = ""
    var type: String = ""
    var location: String = ""
    var image: String = ""
    var activity: String = ""
    var rating: String = ""
    var latitude: Double = 0.0
    var longitude: Double = 0.0
    var distance: Double {
        get {
            return CLLocation(latitude: latitude, longitude: longitude).distance(from: currentLocation!)
        }
    }

    init(locationInfo:[String:Any]) {
        self.id = locationInfo["id"] as! String
        self.name = locationInfo["name"] as! String
        self.type = locationInfo["type"] as! String
        self.location = locationInfo["location"] as! String
        self.image = locationInfo["image"] as! String
        self.activity = locationInfo["activity"] as! String
        self.latitude = locationInfo["latitude"] as! Double
        self.longitude = locationInfo["longitude"] as! Double
}

    public var coordinate: CLLocationCoordinate2D { get {
        let coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
        return coordinate
        }
    }

}

以下是 LocationTableViewController.swift 中的相关部分:

class LocationTableViewController: UITableViewController {

    var locations = [Location]()

    override func viewDidLoad() {
        super.viewDidLoad()

        let locationService: LocationService = LocationService()
        locations = locationService.readLocation()
        locations.sort { $0.distance < $1.distance }
        self.tableView.reloadData()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        tableView.reloadData()
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cellIdentifier = "cell"
        let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! LocationTableViewCell

        // Configure the cell
        cell.nameLabel.text = locations[indexPath.row].name
        cell.thumbnailImageView.image = UIImage(named: locations[indexPath.row].image)
        cell.locationLabel.text = locations[indexPath.row].location
        cell.typeLabel.text = locations[indexPath.row].type
        return cell
    }
}

这是我在 AppDelegate 中实现的,用于捕获用户的位置:

import UIKit
import CoreLocation

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate {

    var window: UIWindow?
    var locationManager:CLLocationManager!
    private var currentCoordinate:CLLocationCoordinate2D?
    var currentLocation:CLLocation?

    static var locations: Array<Location> = Array()

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.

        // Location Manager
        func setupLocationManager() {
            locationManager = CLLocationManager()
            locationManager?.delegate = self
            self.locationManager?.requestAlwaysAuthorization()
            locationManager?.desiredAccuracy = kCLLocationAccuracyBest
            locationManager?.startUpdatingLocation()
            }
        }

        return true
    }

    // Location Manager
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        if currentLocation == nil {
            currentLocation = locations.last
            locationManager?.stopMonitoringSignificantLocationChanges()
            let locationValue:CLLocationCoordinate2D = manager.location!.coordinate
            print("locations = \(locationValue)")
            locationManager?.stopUpdatingLocation()
        }
    }

【问题讨论】:

    标签: swift xcode sorting distance cllocationmanager


    【解决方案1】:

    在您的 Location 模型中定义了另一个属性,称为 distance。这是与用户当前位置的距离。

    var distance: Double {
            get {
                return CLLocation(latitude: latitude , longitude: longitude).distance(from: userLocation)
            }
        }
    

    这将返回CLLocationDistance 中的距离,但您可以将其用作 Double,因为它在排序时很容易。

    现在您可以像这样按升序排列locations 并重新加载数据

    var locations = [Location]()
    
    locations.sort { $0.distance < $1.distance  }
    
    self.tableView.reloadData()
    

    【讨论】:

    • 谢谢!这可能是一个新手错误,但我收到一条错误消息“使用未解析的标识符'userLocation'。”这是因为我需要定义 userLocation 吗?我应该在哪里做这个?
    • @joshlorschy 您必须将用户位置保存在全局或某些共享实例中。这取决于你
    • 我可以在 Location.swift 模型中做吗?还是应该在 AppDelegate 中?
    • @joshlorschy 如果你使用 Location 模型,你必须将它传递给所有对象。所以效率不高。
    • 你能解释一下我该怎么做吗?抱歉,我对编码很陌生!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-21
    • 1970-01-01
    • 2017-05-15
    • 2015-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多