I want to sort my TableView by distance, but I have mixed up:( Please help me if You can, I would appreciate it, really :(
I have an array with 100 objects.
It sounds like you want to sort your array of malls based on their distance to the user's current location.
I would suggest you add a var distanceToUser
to the Mall object. (Make it an optional Double)
In locationManager.didUpdateLocations()
, loop through the array of malls and use the CLLocation
distance(from:)
function to calculate the distance from the new user location to each mall, and store that value in each mall's distanceToUser
property.
Once you have populated the distanceToUser
properties of your array of malls, you can sort the array by that property. Finally, call your table view's reloadData()
method. Write your tableView(cellForRowAt:)
method to display your cells in the existing array order.
The reason to include a distance property in your mall objects is performance. The location manager function to calculate the distance between 2 points is actually somewhat time-consuming (It has to do 3D trig in order to get an accurate calculate on the surface of the globe.) You want to avoid calculating the distance value over and over. Instead, by batch-calculating the distance to a newly updated location, sorting can treat the distance values as known constants that are calculated once per Mall object when the location changes.
If you have a lot of mall objects you might need to do the distance calculations in a background thread and then call the main thread to reload your table view once the calculations are complete, but you can write your calculation code to run on the main thread and then go back and refactor it if you find your UI lags when there is a location update.
You'll also want to configure the location manager to only update the current location when it changes by fairly large amounts. Either that or put in code that compares the new location to the old one and only re-sorts the malls array if the distance has changed enough to affect the sort order of your Malls array. (At the highest sensitivity reading, the location manager gives you an almost constant stream of tiny location changes, which would mean you were recalculating your distances and re-sorting your Malls array constantly.)
You have to choose the index of your array:
let mallLocate = CLLocation(latitude: malls[0].latitude, longitude: malls[0].longitude)
Use of unresolved identifier 'mall'
=> There is nothing named "mall" in the scope of the function locationManager didUpdateLocations
. Meaning: locationManager didUpdateLocations
has no clue what happens inside of tableView cellForRowAt indexPath
and vice versa.
You could solve this problem by applying following steps to your code:
locationManager didUpdateLocations
tableView cellForRowAt indexPath
add a property to your class that stores the current position:
var currentPosition: CLLocation? = nil
Store the position you receive in locationManager didUpdateLocations
to the currentPosition
property
self.tableView.reloadData()
after you received and assigned the position mall
and the currentPosition
in cellForRowAt
to calculate the distance and update the distanceLabel
currentPosition
can be nil
and the distance can not be calculated => make label empty or add something like "unknown distance" to it