Test 87
Test 87

Reputation: 111

How to fix repeating search result in UITableView

I have a UITableView with search bar function. However, when i search for any keyword (Please refer to screenshot as attached), search result will be repeated and return more than 1 result.

My expected result should be search result will reflect accordingly based on keyword entered.

Your help is much appreciated. Please help, thank you. enter image description here enter image description here

 @interface Friend_ViewController () 

@end @implementation Friend_ViewController{ NSMutableArray *tableData; UITableView *tableView; BOOL isFiltered; NSMutableArray *stateNamesArray; NSArray *searchResult; } - (void)viewDidLoad { [super viewDidLoad]; isFiltered =false; UIImage* image3 = [UIImage imageNamed:@"Add_Friend"]; CGRect frameimg = CGRectMake(0,0, image3.size.width -10, image3.size.height); UIButton *btn_add_friends = [[UIButton alloc] initWithFrame:frameimg]; [btn_add_friends setBackgroundImage:image3 forState:UIControlStateNormal]; [btn_add_friends addTarget:self action:@selector(addFriendButtonDidPressed:) forControlEvents:UIControlEventTouchUpInside]; [btn_add_friends setShowsTouchWhenHighlighted:YES]; UIBarButtonItem *btn_add_friends_item =[[UIBarButtonItem alloc] initWithCustomView:btn_add_friends]; self.navigationItem.rightBarButtonItem =btn_add_friends_item; stateNamesArray = @[@"Alabama", @"Alaska", @"Arizona", @"Arkansas", @"California", @"Colorado", @"Connecticut", @"Delaware", @"Florida", @"Georgia", @"Hawaii", @"Idaho", @"Illinois", @"Indiana", @"Iowa", @"Kansas", @"Kentucky", @"Louisiana", @"Maine", @"Maryland", @"Massachusetts", @"Michigan", @"Minnesota", @"Mississippi", @"Missouri", @"Montana", @"Nebraska", @"Nevada", @"New Hampshire", @"New Jersey", @"New Mexico", @"New York", @"North Carolina", @"North Dakota", @"Ohio", @"Oklahoma", @"Oregon", @"Pennsylvania", @"Rhode Island", @"South Carolina", @"South Dakota", @"Tennessee", @"Texas", @"Utah", @"Vermont", @"Virginia", @"Washington", @"West Virginia", @"Wisconsin", @"Wyoming"]; NSInteger indexLabelLettersCount = [[UILocalizedIndexedCollation currentCollation] sectionTitles].count; NSMutableArray *allSections = [[NSMutableArray alloc] initWithCapacity:indexLabelLettersCount]; for (int i = 0; i < indexLabelLettersCount; i++) { [allSections addObject:[NSMutableArray array]]; } for(NSString *theState in stateNamesArray){ NSInteger sectionNumber = [[UILocalizedIndexedCollation currentCollation] sectionForObject:theState collationStringSelector:@selector(lowercaseString)]; [allSections[sectionNumber] addObject:theState]; } NSMutableArray *sortedArray = [[NSMutableArray alloc] init]; self.activeSectionIndices = [NSMutableDictionary dictionary]; self.activeSectionTitles = [NSMutableArray array]; for (int i = 0; i < indexLabelLettersCount; i++) { NSArray *statesForSection = allSections[i]; NSString *indexTitleForSection = [[UILocalizedIndexedCollation currentCollation] sectionTitles][i]; if (statesForSection.count > 0) { [self.activeSectionTitles addObject:indexTitleForSection]; NSArray *tmpSectionStates = allSections[i]; tmpSectionStates = [tmpSectionStates sortedArrayUsingSelector:@selector(compare:)]; [sortedArray addObject:tmpSectionStates]; } NSNumber *index = [NSNumber numberWithInt:MAX(self.activeSectionTitles.count - 1, 0)]; self.activeSectionIndices[indexTitleForSection] = index; } tableData = sortedArray; self.tableView.sectionHeaderHeight = 25; self.navigationController.navigationBar.translucent = NO; tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain]; self.navigationController.navigationBar.translucent = NO; self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero]; self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil]; self.tableView.tableHeaderView = self.searchController.searchBar; self.searchController.searchResultsUpdater = self; self.searchController.dimsBackgroundDuringPresentation = NO; self.searchController.hidesNavigationBarDuringPresentation = NO; self.searchController.searchBar.delegate = self; self.definesPresentationContext = YES; [self.searchController.searchBar sizeToFit]; [self.view addSubview:self.searchBar]; searchResult = [NSMutableArray arrayWithCapacity:[stateNamesArray count]]; } - (void)searchBar:(UISearchBar *)searchBar textDidChange:(nonnull NSString *)searchText { if(searchText.length == 0) { isFiltered = NO; } else { isFiltered = YES; NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"SELF CONTAINS %@", searchText]; searchResult = [stateNamesArray filteredArrayUsingPredicate:resultPredicate]; } [self.tableView reloadData]; } - (NSInteger)numberOfSectionsInTableView: (UITableView *) tableView{ return tableData.count; } - (NSInteger)tableView: (UITableView *)tableView numberOfRowsInSection:(NSInteger)section { if(isFiltered){ return searchResult.count; } else { NSArray *arr = tableData[section]; return arr.count; } } - (UITableViewCell *) tableView:(UITableView *) tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"]; if(cell == nil){ cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"]; } if(isFiltered){ cell.textLabel.text = [searchResult objectAtIndex:indexPath.row]; cell.imageView.image = [UIImage imageNamed:@"Home"]; } else{ NSArray *arr = tableData[indexPath.section];//get the current section array cell.textLabel.text = arr[indexPath.row];//get the row for the current section cell.imageView.image = [UIImage imageNamed:@"Home"]; } return cell; } -(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{ if(isFiltered) { return nil; } return self.activeSectionTitles[section]; } @end </pre></code>

Upvotes: 1

Views: 102

Answers (3)

Indrajeet
Indrajeet

Reputation: 5666

update this code

 - (void)searchBar:(UISearchBar *)searchBar textDidChange:(nonnull NSString *)searchText
{ 
   //Add below line of code
    [searchText removeAllObjects];
    if(searchText.length == 0)
    {
        isFiltered = NO;
    }
    else
    {
        isFiltered = YES;
        NSPredicate *resultPredicate = [NSPredicate
                                    predicateWithFormat:@"SELF CONTAINS %@",
                                    searchText];    
        searchResult = [stateNamesArray filteredArrayUsingPredicate:resultPredicate];      
    }
    [self.tableView reloadData];
}

This method calls on every character, so it search and result store in array. You are not removing object from array so it keep adding object in it. That's why you are getting this result.

[searchText removeAllObjects];

This line of code remove all objects from array.

Upvotes: 0

Pooja Gupta
Pooja Gupta

Reputation: 793

You are always returning tableData.count in numberOfSectionsInTableView so every row is repeated tableData.count times.

- (NSInteger)numberOfSectionsInTableView: (UITableView *) tableView{
   return isFiltered ? 1 : tableData.count;
}


- (NSInteger)tableView: (UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  NSArray sectionArray = (NSArray *)tableData[section];
  return isFiltered ? 1 : sectionArray.count;
}

You are always returning tableData.count in numberOfSectionsInTableView so

Upvotes: 1

Arun Kumar
Arun Kumar

Reputation: 798

You need to return proper section count.

- (NSInteger)numberOfSectionsInTableView: (UITableView *) tableView{

    return isFiltered ? 1 : tableData.count;
}

I hope this will help you. :)

Upvotes: 0

Related Questions