按计算距离对 UITableView 单元格进行排序(解析)

Order UITableView cells by calculated distance (Parse)

我在解析时创建的数据库有问题。我有一个 table 显示了各个本地有多少英里(一旦您从 DB 下载列表)问题是我会按向上的距离订购它,但我不知道该怎么做。我用来计算距离的代码是这样的:

- (id)initWithCoder:(NSCoder *)aCoder
{
    self = [super initWithCoder:aCoder];
    if (self) {
        // Custom the table

        // The className to query on
        self.parseClassName = @"Ristoranti";

        // The key of the PFObject to display in the label of the default cell style
        self.textKey = @"NomeLocale";

        // Whether the built-in pull-to-refresh is enabled
        self.pullToRefreshEnabled = YES;

        // Whether the built-in pagination is enabled
        self.paginationEnabled = YES;

        // The number of objects to show per page
        self.objectsPerPage = 100;
    }
    return self;
}


- (void)viewDidLoad
{
    [super viewDidLoad];

    locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate = self;
    locationManager.distanceFilter = kCLDistanceFilterNone;
    locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;

    if(IS_OS_8_OR_LATER) {

        [locationManager requestWhenInUseAuthorization];
        [locationManager requestAlwaysAuthorization];
    }

    [locationManager startUpdatingLocation];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(refreshTable:)
                                                 name:@"refreshTable"
                                               object:nil];
}

- (void)refreshTable:(NSNotification *) notification
{
    // Reload the recipes
    [self loadObjects];
}


- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"refreshTable" object:nil];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

- (PFQuery *)queryForTable
{
    PFQuery *query = [PFQuery queryWithClassName:self.parseClassName];

    query.limit = 100;

    [query orderByAscending:@"createdAt"];

    return query;   
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object
{
    static NSString *simpleTableIdentifier = @"RecipeCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
    if (cell == nil) {

            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
    }

    NSString *AntDef = [NSString stringWithFormat:@"%@", [object objectForKey:@"AnteprimaDefault"]];

    if ([AntDef isEqualToString:@"Null"])
    {   
        PFImageView *thumbnailImageView = (PFImageView*)[cell viewWithTag:100];
        thumbnailImageView.image = [UIImage imageNamed:@"ImageDefault.png"];
        thumbnailImageView.layer.cornerRadius = thumbnailImageView.frame.size.width / 2;
        thumbnailImageView.clipsToBounds = YES;
        thumbnailImageView.layer.borderWidth = 0.5;
        thumbnailImageView.layer.borderColor = [UIColor lightGrayColor].CGColor;
    }

    else
    {   
        PFFile *thumbnail = [object objectForKey:@"Anteprima1"];
        PFImageView *thumbnailImageView = (PFImageView*)[cell viewWithTag:100];
        thumbnailImageView.image = [UIImage imageNamed:@"placeholder.jpg"];
        thumbnailImageView.file = thumbnail;
        thumbnailImageView.layer.cornerRadius = thumbnailImageView.frame.size.width / 2;
        thumbnailImageView.clipsToBounds = YES;
        [thumbnailImageView loadInBackground];
    }



    Lat = [[object objectForKey:@"Latitudine"] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    Long = [[object objectForKey:@"Longitudine"] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

    Latdouble = [Lat doubleValue];
    Longdouble = [Long doubleValue];


    NSArray *locations = [NSArray arrayWithObjects:[[CLLocation alloc] initWithLatitude:Latdouble longitude:Longdouble], nil];

    //NSLog(@"LOCATIONS COORDINATE: %@", locations);

    CLLocation *currentLocation = [[CLLocation alloc] initWithLatitude:locationManager.location.coordinate.latitude longitude:locationManager.location.coordinate.longitude];;
    CLLocation *nearestLoc = nil;
    CLLocationDistance nearestDis = FLT_MAX;

    for (CLLocation *location in locations) {
        CLLocationDistance distance = [currentLocation distanceFromLocation:location];

        for (CLLocation *location in locations) {
            distance = [currentLocation distanceFromLocation:location];
            if (nearestDis > distance) {
                nearestLoc = location;
                nearestDis = distance;
            }
        }

        text12 = [NSString  stringWithFormat:@"%.1f Km", nearestDis/1000];
    }

...
}

提前致谢:)

假设您来自 Parse.com 的响应数据是 NSArray

我建议:

  • 执行请求。
  • 排序 NSArray
  • 重新加载数据。

可以使用以下块对数组进行排序:sortedArrayUsingComparator:^NSComparisonResult(id a, id b)

NSArray *sortedArray;
sortedArray = [initialDataArray sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
   //Here do the method to compare if `a` is closer or `b` is closer
   YourParseObject *aObject = (YourParseObject *)a;
   YourParseObject *bObject = (YourParseObject *)b;
   //Get Latitude & Longitude from a and b.
   //return NSOrderedAscending or NSOrderedDescending according to which one of a or b is the closest, using your previous method I suppose to be working.

}];

所以 sortedArray 看起来像这样:

{
 YourParseObject the closest one
 YourParseObject the second closest one
 //...
 YourParseObject the farthest one.
}

一旦完成:

[yourTableView reloadData]

我今天刚遇到这个问题,发现Parse.com已经实现了这个解决方案:

如果您正在使用 Parse 的 PFQueryTableViewController.h,您需要将其添加到您的 queryForTable 方法中:

  • (PFQuery *)queryForTable {
 PFQuery *query = [PFQuery queryWithClassName:self.parseClassName];    
        [query whereKey:@"yourClassPFLocationField" nearGeoPoint:yourLocation];
    return query;
}

如果您不使用 PFQueryTable,同样适用,只需在加载查询时使用该排序方法即可。

一切都在 PFQuery 文档中 :D