我在這裏看到很多關於這個問題的文章,但似乎沒有解決我遇到的問題。在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]];
}
}
}
}