1

我在这里看到很多关于这个问题的文章,但似乎没有解决我遇到的问题。在UITableView中排序核心数据对多关系

我有一个使用核心数据的应用程序。我试图排序一个tableViews连接到一个NSFetchedResultsController,是什么让这个问题比其他一些帖子更复杂的是,我需要根据用户的位置更新排序。

我的场景如下:

我有一个名为Store的实体。商店有很多分支,每个分支都有自己的经纬度。我有一个tableview显示所选商店的所有分支。我想要的是,当用户更新他们的位置,而tableview可见时,单元格更新他们的位置,以便tableview排序与顶部最近的分支。

我设法得到所有这些工作正常与单元格动画上下移动时,用户移动更接近分支等。但我的解决方案不仅效率低下,但也有一个主要的bug,当tableview有更多的细胞可以放在屏幕上。

我知道最可能的路线是使用NSOrderedSet对Store实体上的多对多关系进行排序。但不知道如何实现这一点,因为我排序的值不存储在核心数据中,但是如果有意义的话可以动态计算。纬度和长度被存储,但是距离是在飞行中计算的,并且它的距离值决定了排序。

当前我使用CLLocationManger协议locactionManager:didUpdateLocations来调用updateCellSortingOrder这是我的排序方法。位置管理器设置为:

self.manager.desiredAccuracy = kCLLocationAccuracyBestForNavigation; 

我的排序方法有效,但就像我说的那样不理想。我希望能够利用尽可能多的核心数据工具,如NSFetchedViewController,谓词,聚合等,而不是创建数组,然后对它们进行排序,然后将它们推回到FRC等等,这就是我现在正在做的事情....太乱了。

这里是我的代码,branchCell是的UITableViewCell的子类,具有保持分支属性初始化。 是我的实体店

//Creating the branch cell 
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
static NSString *CellIdentifier = @"MyTableCellView"; 

BranchCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
if (cell == nil) { 
    cell = [[BranchCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; 


    Branch *currentBranch = [[self.list.listsToDelivery allObjects] objectAtIndex:indexPath.row]; 

    cell.branch = currentBranch; 
    cell.textLabel.text = currentBranch.title; 
} 

return cell; 

}

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations 
{ 
    //update the cells 
    [self updateCellSortingOrder]; 
} 

- (void) updateCellSortingOrder 
{ 
    // get the number of cells 
    static int numberOfCells; 

    numberOfCells = [[self.currentStore.branches allObjects] count]; 

//loop though all the cells 
    for (int cellAIndex = 0; cellAIndex < numberOfCells; cellAIndex++) 
{ 
    //set up the cells 
    static BranchCell * cellA; 
    static BranchCell * cellB; 

    //branch instances 
    static Branch *branchA; 
    static Branch *branchB; 

    //distances 
    static CLLocationDistance distanceA; 
    static CLLocationDistance distanceB; 
    static CLLocation *locationA; 
    static CLLocation *locationB; 

    //second loop to get the next cell 
    for (int cellBIndex = cellAIndex+1; cellBIndex < numberOfCells; cellBIndex++) 
    { 
     //assign the cells 
     cellA = (BranchCell *)[self.myTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:cellAIndex inSection:0]]; 
     cellB = (BranchCell *)[self.myTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:cellBIndex inSection:0]]; 

     //get the two branches which we need to compate 
     branchA = cellA.branch; 
     branchB = cellB.branch; 

     //calculate the distance 
     locationA = [[CLLocation alloc] initWithLatitude:branchA.address.region.center.latitude longitude:branchA.address.region.center.longitude]; 

     locationB = [[CLLocation alloc] initWithLatitude:branchB.address.region.center.latitude longitude:branchB.address.region.center.longitude]; 

     distanceA = [self.manager.location distanceFromLocation:locationA]; 
     distanceB = [self.manager.location distanceFromLocation:locationB]; 

     //move the cell a to cell b's location if a's distances is greater than b's 
     if (distanceA > distanceB) 
     { 
      [self.myTableView moveRowAtIndexPath:[NSIndexPath indexPathForRow:cellAIndex inSection:0] toIndexPath:[NSIndexPath indexPathForRow:cellBIndex inSection:0]]; 

     } 
    } 
} 
} 

回答

0

在任何情况下,一个也面临同样的问题,我有一个实例,这里是我的修补程序。修正了一段时间,但从未更新。它在我的应用程序交付这是对现在应用商店:)使用

的updateCellSortingOrder被称为在地图上的委托方法的MapView:didUpdateUserLocation:

  • (无效)updateCellSortingOrder {

    [self.myTableView reloadData];

    [self。sortedCellArray sortUsingComparator:^(交付* deliveryA,送货* deliveryB) {

    CLLocationDistance distanceA; 
    CLLocationDistance distanceB; 
    
    
    distanceA = [[self.mapView userLocation] distanceFromLocation: deliveryA.address]; 
    distanceB = [[self.mapView userLocation] distanceFromLocation: deliveryB.address]; 
    
    if (distanceA > distanceB) 
    { 
    
        return (NSComparisonResult)NSOrderedDescending; 
    } 
    
    return (NSComparisonResult)NSOrderedSame; 
    

    }];

}