Repopulating UITableView after search

本小妞迷上赌 提交于 2019-12-13 06:05:18

问题


I'm using single NSFetchedResultController to populate both self.tableView and UISearchDisplayControler.tableView. After using search bar and dismissing it if I select any row in the self.tableView I get this error:

Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array'

I guess that somewhere I miss reloading data but I have no clue where? Here are some methods which I use for populating both tabble views:

#pragma mark - Table View

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Count sections in FRC
    return [[self.groupsFRC sections] count];
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Count groups in each section of FRC
    return [[[self.groupsFRC sections] objectAtIndex:section] numberOfObjects];
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Get reusable cell
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"GroupCell"];

    // If there isn't any create new one
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"GroupCell"];
    }

    Group *group = [self.groupsFRC objectAtIndexPath:indexPath];

    cell.textLabel.text = group.name;

    // Checking if group has been selected earlier
    if ([self.selectedGroups containsObject:@{@"name" : group.name, @"id" : group.cashID}]) {
        [cell setAccessoryType:UITableViewCellAccessoryCheckmark];
    } else {
        [cell setAccessoryType:UITableViewCellAccessoryNone];
    }

    return cell;
}

// Adding checkmark to selected cell
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
    Group *group = [self.groupsFRC objectAtIndexPath:indexPath];

    // Checking if selected cell has accessory view set to checkmark and add group to selected groups array
    if (selectedCell.accessoryType == UITableViewCellAccessoryNone)
    {
        selectedCell.accessoryType = UITableViewCellAccessoryCheckmark;
        [self.selectedGroups addObject:@{@"name" : group.name, @"id" : group.cashID}];
        NSLog(@"%@", self.selectedGroups);
    }
    else if (selectedCell.accessoryType == UITableViewCellAccessoryCheckmark)
    {
        selectedCell.accessoryType = UITableViewCellAccessoryNone;
        [self.selectedGroups removeObject:@{@"name" : group.name, @"id" : group.cashID}];
        NSLog(@"%@", self.selectedGroups);
    }

    // Hiding selection with animation for nice and clean effect
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
}

#pragma mark - Filtering

- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
    NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"SELF.name contains[c] %@", searchText];
    self.groupsFRC = [Group MR_fetchAllSortedBy:@"caseInsensitiveName"
                                      ascending:YES
                                  withPredicate:resultPredicate
                                        groupBy:@"sectionLetter"
                                       delegate:self];
}

-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
    [self filterContentForSearchText:searchString
                               scope:[[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:[self.searchDisplayController.searchBar selectedScopeButtonIndex]]];
    return YES;
}

-(void)searchDisplayController:(UISearchDisplayController *)controller didHideSearchResultsTableView:(UITableView *)tableView
{
    // Setting FRC to fetch original table view data
    self.groupsFRC = [Group MR_fetchAllSortedBy:@"caseInsensitiveName"
                                      ascending:YES
                                  withPredicate:nil
                                        groupBy:@"sectionLetter"
                                       delegate:self];
}

回答1:


Okey, I finally get over this problem but with skipping UISearchDisplayDelegate and implementing this only using UISearchBarDelegate. Here is the code:

-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
    if (searchText.length > 0) {
        resultPredicate = [NSPredicate predicateWithFormat:@"SELF.name contains[c] %@", searchText];
    } else {
        resultPredicate = nil;
    }

    [self refreshFRC];
}

-(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
    resultPredicate = nil;
    [self refreshFRC];
}

- (void)refreshFRC {
    if (resultPredicate != nil) {
        self.groupsFRC = [Group MR_fetchAllSortedBy:@"caseInsensitiveName"
                                          ascending:YES
                                      withPredicate:resultPredicate
                                            groupBy:@"sectionLetter"
                                           delegate:self];
    } else {
        self.groupsFRC = [Group MR_fetchAllSortedBy:@"caseInsensitiveName"
                                          ascending:YES
                                      withPredicate:nil
                                            groupBy:@"sectionLetter"
                                           delegate:self];
        [self.tableView reloadData];
    }
}


来源:https://stackoverflow.com/questions/20983333/repopulating-uitableview-after-search

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!