如何修复 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 中的重复搜索结果的主要内容,如果未能解决你的问题,请参考以下文章

如何过滤 UITableView 中的重复数据

聚焦时如何修复 UISearchController 搜索栏调整大小?

UITableView中的节标题视图重复

Iphone:UITableView 标题行在 6 行后重复

如何修复 JSON 不填充我的 UITableView?

UITableView,如何修复页脚,使其在滚动时永远不会向上或向下移动?