我在这里看到很多关于这个问题的文章,但似乎没有解决我遇到的问题。在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]];
}
}
}
}