从坐标数组到表格的位置之间的距离

时间:2016-05-24 20:22:03

标签: ios swift swift2 core-location

我尝试使用行来填充表格,这些行显示距离用户当前位置与坐标数组的位置的距离。我有一个空数组中的坐标,我有用户的位置。

我坚持将坐标数组转换为函数来计算距离,然后将每个距离值放入表格行的标签中。非常感谢任何见解。

var locationArray: [CLLocationCoordinate2D] = []
var shopperLocation = String()
var distanceText: [String] = []

func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    let userLocation:CLLocation = locations[0]

    shopperLocation = userLocation

    self.manager.stopUpdatingLocation()
}

//This is the function I am trying to use to get distance from the array of coordinates //

func distanceToLocation(){

    if locationArray == nil {

        locationArray = userLocation
    }

    let distanceBetween: CLLocationDistance =   shopperLocation.distanceFromLocation(startLocation) / 1609.34

    let distanceInMilesFromUser = String(format: "%.2f", distanceBetween)

    distanceText = "\(distanceInMilesFromUser) mi"
   }

  // Here I am trying to get the distance values in the correct rows //

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! listViewCell

    cell.myDistance.text = distanceText[indexPath.row]

    return cell
}

2 个答案:

答案 0 :(得分:2)

这是因为您必须明确告诉表视图重新加载数据,即再次询问其TableViewDataSource是否为每个单元配置了新数据。

您可以通过tableView.reloadData()委托方法中的CLLocationManager轻松完成此操作。下面的代码是实现这一目标的一种方法。顺便说一句,几句话:

  • 我发现使用var myArray: [Type]()初始化数组比提供显式类型然后分配空数组更优雅

  • 您最好在结构中保存商店参数(名称,坐标等)

  • 跟踪当前用户位置而不是距离;这样做可以让您轻松添加新商店而无需再次请求用户位置

  • 使用MKDistanceFormatter为您的距离提供一个人性化的可读文本输出 - 这非常强大,可以免费适应您用户的区域设置和首选单位系统!

不要忘记导入所有必需的模块:

import UIKit
import CoreLocation
import MapKit

定义常量:

let locationCellIdentifier = "LocationCell"

和你的结构:

struct Shop {
    let name: String
    let coordinates: CLLocation
}

然后你的视图控制器:

final class LocationTableView: UITableViewController, CLLocationManagerDelegate {

    var shops = [Shop]()
    var userLocation: CLLocation?
    let distanceFormatter = MKDistanceFormatter()

    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

        // Save the location and reloads table view
        if !locations.isEmpty {
            userLocation = locations.first
            manager.stopUpdatingLocation()
            tableView.reloadData()
        }
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return shops.count
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier(locationCellIdentifier, forIndexPath: indexPath)

        // Configure the cell
        let shop = shops[indexPath.row]
        cell.textLabel?.text = shop.name

        if let userLocation = userLocation {
            let distance = shop.coordinates.distanceFromLocation(userLocation)
            let formattedDistance = distanceFormatter.stringFromDistance(distance)
            cell.detailTextLabel?.text = formattedDistance
        } else {
            cell.detailTextLabel?.text = nil
        }

        return cell
    }
}

答案 1 :(得分:1)

现在这看起来很粗糙,所以我会尝试根据你想要做的事情以及你似乎遇到的问题给出一个大纲。

首先你有一个locationArray,但是它是空的,我假设你会填充它。

你也有一个distanceText数组,所以这里有一个建议的方法。 (并且没有经过测试或验证,因此将其视为psudeo代码)。

当您的位置更新时

  1. 获取最后一个位置(最近的位置)
  2. 将当前位置数组映射到新的distanceText数组。
  3. 请求tableView重新加载它的数据。

    var locationArray: [CLLocationCoordinate2D] = [] 
    var distanceText: [String] = []
    
    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let userLocation = locations.last
        distanceText = locationArray.map { location in 
            // add your code to calculated the distance and return it
            let distanceAsText = .......  // some function of location and userLocation
            return distanceAsText
        }
        tableView?.reloadData()        
    }