distanceInMeters Problems with arrays and sort

后端 未结 3 1827
野性不改
野性不改 2020-12-04 03:54

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.

相关标签:
3条回答
  • 2020-12-04 04:41

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

    0 讨论(0)
  • 2020-12-04 04:43

    You have to choose the index of your array:

    let mallLocate = CLLocation(latitude: malls[0].latitude, longitude: malls[0].longitude)
    
    0 讨论(0)
  • 2020-12-04 04:52

    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:

    1. Move the distance calculation from
      locationManager didUpdateLocations
      to
      tableView cellForRowAt indexPath
    2. add a property to your class that stores the current position:
      var currentPosition: CLLocation? = nil

    3. Store the position you receive in locationManager didUpdateLocations to the currentPosition property

    4. Add self.tableView.reloadData() after you received and assigned the position
    5. Use the mall and the currentPosition in cellForRowAt to calculate the distance and update the distanceLabel
    6. Keep in mind that currentPosition can be nil and the distance can not be calculated => make label empty or add something like "unknown distance" to it
    0 讨论(0)
提交回复
热议问题