prateek arora
prateek arora

Reputation: 21

Updating UITableView while UISearchBar is active

I am writing an iOS chat application wherein I have to show the users list with a search bar. I am getting the updated user list from the server after every 2 min.

The problem that I am facing is

Case:1 If I have the search bar active and I call reload table when the datasource is updated, now if I cancel the search, I do not get my original table. Only the filtered results are shown.

Case: 2 If I have the search bar active and I just update the data source and do not reload the table, now if I cancel the search, it loops to cellforrowatindexpath as many times as there are elements in the new datasource but it does not show the updated elements. Infact, it jumbles up the elements because it considers the new index paths but uses the old data.

By jumbled up I mean,

  1. Say if the old datasource is a1, a2, a3 and a4 with avatar images a1, a2, a3, a4.

  2. The new datasource is a5, a1, a2, a3, a4 with images a5, a1, a2, a3, a4.

  3. So the jumbled view that I get is a1 with a5 image, a2 with a1 image, a3 with a4 image a4 with no image.

4 cells instead of 5.

Case: 3 (working correctly) If I have the search bar active and I do not even update the data source, nothing happens when I cancel the search (as expected). I have to reload the table to get the updated view.

What I want is that it should update the table even if search is active and when I cancel the search I should get the updated table view. I know this can be achieved by reload table when cancel button is clicked but I am trying to find an elegant solution to this.

Also, please tell me the concept (the inner workings) behind why is this working like this.

My code:

- (void)refreshUserList
{
    if(dtclass.updatedUserList && [resultsArray count] ==0)
    {
        userArray = dtclass.getUpdatedUserList;
        [self.tableView reloadData];
        [dtclass setUpdatedUserList:NO];
    }
    else if(dtclass.updatedUserList && [resultsArray count] !=0)
    {
        //Uncomment for Case:1
        /*userArray = dtclass.getUpdatedUserList;
        [dtclass setUpdatedUserList:NO];
        [self.tableView reloadData];*/

        //Uncomment for Case:2
        /*userArray = dtclass.getUpdatedUserList;
        [dtclass setUpdatedUserList:NO];*/

        //remove else if code for Case:3
    }
}


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:    (NSInteger)section
{

    if (resultsArray.count != 0)
    {
        return [resultsArray count];
    }

    return userArray.count;
}


-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

    [tableView setSeparatorInset:UIEdgeInsetsMake(0, 70, 0, 0)];

    GlobalListTableViewCell *cell = (GlobalListTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"GlobalListCell"];

    if (cell == nil)
    {
        NSArray *nib = [[NSBundle mainBundle]     loadNibNamed:@"GlobalListTableViewCell" owner:self options:nil];
        cell = [nib objectAtIndex:0];
    }
    //custome class User
    User *currentUser;

    if(resultsArray.count !=0)
    {
        currentUser = [resultsArray objectAtIndex:indexPath.row];
    }
    else
    {
        currentUser = [userArray objectAtIndex:indexPath.row];
    }

    cell.nameLabel.text = currentUser.getName;
    cell.timeLabel.text = @"5 pm";

    dispatch_async(fetchImage, ^{

        if([[currentUser getAvatarUrl] length]!=0)
        {
            [self loadImagesWithURL:[NSString stringWithFormat:@"%@%@",@"http:",[currentUser getAvatarUrl]] IndexPath:indexPath];
        }
    });


    cell.avatarImage.image = [UIImage imageNamed:@"defaultUser.png"];
    cell.messageLabel.text = @"No message";

    return cell;
}

-(void) loadImagesWithURL:(NSString *)imageURL IndexPath:(NSIndexPath *)indexPath
{
    NSURL *url = [NSURL URLWithString:imageURL];
    NSData *data = [[NSData alloc ] initWithContentsOfURL:url];

    UIImage *img = [UIImage imageWithData:data];

    dispatch_async(dispatch_get_main_queue(), ^{

        GlobalListTableViewCell *cell = (GlobalListTableViewCell *)[self.tableView cellForRowAtIndexPath:indexPath];
        cell.avatarImage.image = img;

    });
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:   (NSIndexPath *)indexPath
{
    return 60;
}


- (void)filterContentForSearchText:(NSString*)searchText scope:    (NSString*)scope
{
    resultsArray = [[NSArray alloc] init];
    NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"SELF.getName contains[c] %@", searchText];

    resultsArray = [userArray filteredArrayUsingPredicate:resultPredicate];
}

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


    return YES;
}

- (void)searchBarCancelButtonClicked:(UISearchBar *) aSearchBar {
    aSearchBar.text = nil;
}

Upvotes: 1

Views: 1116

Answers (1)

user3783005
user3783005

Reputation: 540

Try this code for search ..

- (void)filterContentForSearchText:(NSString*)searchText
{
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.getName contains[c] %@",searchText];
    _filteredGarages = [NSMutableArray arrayWithArray:[_allGarages filteredArrayUsingPredicate:predicate]];
}

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
    [_filteredGarages removeAllObjects];
    if([searchText length] != 0) {           
        [self filterContentForSearchText:searchText];
    }
    [self.tableView reloadData];
}

- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
    isSearching = NO;
    [self.tableView reloadData];
}

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
    if([searchBar.text isEqualToString:@""])
        isSearching = NO;
    else isSearching = YES;
    [self.tableView reloadData];
}

-(void)searchBarTextDidEndEditing:(UISearchBar *)searchBar
{
    if([searchBar.text isEqualToString:@""])
        isSearching = NO;
    else isSearching = YES;
    [self.tableView reloadData];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    resultsArray = [[NSMutableArray alloc] init];
    isSearching = NO;
    userArray = [[NSMutableArray alloc] init];
    userArray = [//GetYourData//];
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (tableView == self.searchDisplayController.searchResultsTableView) {
        return [resultsArray count];
    } else {
        return [userArray count];
    }
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Do you table view cell job here ...

    if (tableView == self.searchDisplayController.searchResultsTableView) {
        isSearching = YES;
        //fill the cell using resultsArray
    } else {
        //fill the cell using userArray
    }
}

Upvotes: 1

Related Questions