Reputation: 111
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.
@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
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
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
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