如何修复 UITableView 中的重复搜索结果
Posted
技术标签:
【中文标题】如何修复 UITableView 中的重复搜索结果【英文标题】:How to fix repeating search result in UITableView 【发布时间】:2018-01-03 05:14:30 【问题描述】:我有一个带有搜索栏功能的 UITableView。但是,当我搜索任何关键字时(请参阅随附的屏幕截图),搜索结果将重复并返回超过 1 个结果。
我的预期结果应该是搜索结果将根据输入的关键字相应地反映出来。
非常感谢您的帮助。请帮忙,谢谢。
@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>
【问题讨论】:
在插入之前清空 searchResult 数组 【参考方案1】:您总是在 numberOfSectionsInTableView 中返回 tableData.count,因此每一行都重复 tableData.count 次。
- (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;
你总是在 numberOfSectionsInTableView 中返回 tableData.count 所以
【讨论】:
【参考方案2】:您需要返回正确的节数。
- (NSInteger)numberOfSectionsInTableView: (UITableView *) tableView
return isFiltered ? 1 : tableData.count;
我希望这会对你有所帮助。 :)
【讨论】:
【参考方案3】:更新此代码
- (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];
这个方法调用每个字符,所以它搜索和结果存储在数组中。您没有从数组中删除对象,因此它会继续在其中添加对象。这就是你得到这个结果的原因。
[searchText removeAllObjects];
这行代码从数组中删除所有对象。
【讨论】:
以上是关于如何修复 UITableView 中的重复搜索结果的主要内容,如果未能解决你的问题,请参考以下文章
聚焦时如何修复 UISearchController 搜索栏调整大小?