UISearchBar 的按钮标签问题

Posted

技术标签:

【中文标题】UISearchBar 的按钮标签问题【英文标题】:button tag issue with UISearchBar 【发布时间】:2014-01-21 09:38:39 【问题描述】:

我需要为在表格视图单元格上创建的按钮设置一个标签。 我实现了UISearchBar,它运行良好。

问题是在过滤 tableView 单元格后,它的indexpath.row 会随着我的设置而改变'button.tag = indexPath.row'

有没有办法让每个单元格的行号保持不变? 或者有没有其他解决方案?

注意:我在一个UITableView 中有多个部分,isFiltered 是 BOOL 值,表示用户已开始在UISearchBar 中输入文本。

借助https://github.com/kwylez/IndexedTable实现搜索

cellForRowAtIndexPath:

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

    static NSString *cellId = @"CheckBoxedCell";
   // NSString *cellId = [NSString stringWithFormat:@"Section:%d Row:%d",indexPath.section,indexPath.row];
    CheckBoxedCellClass *cell = (CheckBoxedCellClass *)[self.tableViewContact dequeueReusableCellWithIdentifier:cellId];

    if(!cell)
    
        NSArray *nib;
        if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
        
            nib = [[NSBundle mainBundle] loadNibNamed:@"CheckBoxedCellClass" owner:self options:nil];
        
        else if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
        
            nib = [[NSBundle mainBundle] loadNibNamed:@"CheckBoxedCellClass_iPad" owner:self options:nil];
        
            for (id object in nib)
            
                if([object isKindOfClass:[CheckBoxedCellClass class]])
                
                    cell = (CheckBoxedCellClass *)object;
                    break;
                
            

            cell = [nib objectAtIndex:0];

     

        SaveCheckBoxedView *saveContact;
        if(isFiltered == YES)
        
            saveContact = [filterdArray objectAtIndex:indexPath.row];
            cell.nameLabel.text = saveContact.nameString;
        
        else
        
            saveContact = [mutableArray objectAtIndex:indexPath.row];
            cell.nameLabel.text = [[objectsForCharacters objectForKey:[arrayOfCharacters objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row];
        

        //cell.nameLabel.text = saveContact.nameString;

        cell.companyLabel.text = saveContact.companyString;
        cell.invIdLabel.text = [NSString stringWithFormat:@"%d", saveContact.invitId];

        //set fonts
        if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
        

            [cell.companyLabel setFont:[UIFont italicSystemFontOfSize:10.0]];
        
        else
        

            [cell.companyLabel setFont:[UIFont italicSystemFontOfSize:14.0]];
        



    //handling check box

    NSInteger rowNumber = 0;
    for(NSInteger i = 0; i < indexPath.section ; i++)
    
        rowNumber += [self tableView:self.tableViewContact numberOfRowsInSection:i];
    

    rowNumber += indexPath.row;

    /*if([indexPath compare:self.lastIndexPath] == NSOrderedSame)
    
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
        NSString *finalIntId = [mutableArrayOfIds objectAtIndex:rowNumber];
        NSLog(@"Tagged checked button id = %@", finalIntId);
        [arrayOfIds addObject:finalIntId];
    */

    UIButton *checkBox;
    if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
    
        checkBox = [[UIButton alloc]initWithFrame:CGRectMake(7, 8, 30, 30)];
    
    else
    
        checkBox = [[UIButton alloc]initWithFrame:CGRectMake(15, 13, 30, 30)];
    

    [checkBox setImage:[UIImage imageNamed:@"checkBox.png"] forState:UIControlStateNormal];
    [checkBox addTarget:self action:@selector(checkBoxClicked:event:) forControlEvents:UIControlEventTouchUpInside];
    if(isFiltered == YES)
    
        checkBox.tag = ;
    
    else
    
        checkBox.tag = rowNumber;
    
    [cell.contentView addSubview:checkBox];

    return cell;

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView 
    if(isFiltered == YES) 
        return Nil;
     else 
        NSArray *toBeReturned = [NSArray arrayWithArray:
                                 [@"A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|#"
                                  componentsSeparatedByString:@"|"]];
        return toBeReturned;
    


- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index 
    if (title == UITableViewIndexSearch) 
        CGRect searchBarFrame = self.searchDisplayController.searchBar.frame;
        [tableView scrollRectToVisible:searchBarFrame animated:YES];

        return -1;
     else 
        NSInteger count = 0;

        for (NSString *character in arrayOfCharacters) 
            if ([character isEqualToString:title]) 
                return count;
            
            count ++;
        
        return 0;
    


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
    if(isFiltered == YES) 
        return 1;
     else 
        return [arrayOfCharacters count];
        //return 1;
    


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
    if(isFiltered == YES) 
        return [filterdArray count];
     else 
        //return [mutableArray count];
        return [[objectsForCharacters objectForKey:[arrayOfCharacters objectAtIndex:section]] count];
    


- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section 
    if ([arrayOfCharacters count] == 0) 
        return @"";
    

    return [NSString stringWithFormat:@"%@", [arrayOfCharacters objectAtIndex:section]];


- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText

    if(searchText.length == 0)
    
        isFiltered = NO;
    
    else
    
        isFiltered = YES;
        filterdArray = [[NSMutableArray alloc] init];
        for (SaveCheckBoxedView *contact in mutableArray)
        
            NSRange nameRange = [contact.nameString rangeOfString:searchText options:NSCaseInsensitiveSearch];
            if(nameRange.location != NSNotFound)
            
                [filterdArray addObject:contact];
            
        
    
    [self.tableViewContact reloadData];


- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString

    [filterdArray removeAllObjects];
    if(searchString.length > 0)
    
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF contains [search] %@", self.mySearchBar.text];
        for (NSString *key in arrayOfCharacters)
        
            NSArray *matches = [objectsForCharacters[key] filteredArrayUsingPredicate:predicate];
            [filterdArray addObjectsFromArray:matches];
        
    
    return YES;

【问题讨论】:

你的问题不清楚。您希望按钮标签与过滤前相同吗?可以发布您的完整 cellForRowAtIndexPath 方法吗? @Rashad 我添加了 cellForRowAtIndexPath 的整个方法 你想要什么?过滤后按钮标签会保持不变? 当我在不搜索的情况下设置 button.tag = rowNumber 时,它工作正常。当用户开始搜索后过滤行时,rowNumber 会发生变化。所以我需要为过滤后的单元格常量设置 rowNumber搜索栏已启用 您正在重用单元格(这是一个好习惯)。但是,当您重复使用该标签时,您的标签将被重置。您需要重新设计逻辑。你从哪里设置 filterdArray? 【参考方案1】:

我正在描述一种方法,您可能会找到更好的方法。

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString

    [filterdArray removeAllObjects];
    if(searchString.length > 0)
    
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF contains [search] %@", self.mySearchBar.text];
        for (NSString *key in arrayOfCharacters)
        
            NSArray *matches = [objectsForCharacters[key] filteredArrayUsingPredicate:predicate];
            /****see bellow****/
            [filterdArray addObjectsFromArray:matches];
        
    
    return YES;

尝试查找“匹配”的每个对象的行号。那将是您的按钮的标签。使 filterdArray 成为字典数组。将 2 字段添加到字典。一个用于标记另一个用于价值。在 cellForRowAtIndexPath

 if(isFiltered == YES)

    checkBox.tag = [filterdArray objectForKey: @"tag"] ;

else

    checkBox.tag = rowNumber;

【讨论】:

以上是关于UISearchBar 的按钮标签问题的主要内容,如果未能解决你的问题,请参考以下文章

Black Opaque UIToolbar 和 UISearchBar 看起来差别太大了

如何触发 UISearchBar 中的取消按钮?

单击 UISearchBar 的取消按钮后,如何使用 UISearchBar 刷新我的 UITableView?

UISearchBar 在搜索没有结果时显示标签,但在单击 UISearchBar 中的 x 时不会再次隐藏标签

UISearchBar 取消按钮颜色?

UISearchBar 取消