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; 
    

    }];

}