搜索中的第一个 UITableViewCell UIButton 保持不变

Posted

技术标签:

【中文标题】搜索中的第一个 UITableViewCell UIButton 保持不变【英文标题】:First UITableViewCell UIButton in search remains the same 【发布时间】:2014-06-20 01:52:55 【问题描述】:

我有一个可以加载 3 个单元格的表格。第一个单元格的标签文本是“Don”,后两个单元格的标签文本是“Test”。

我注意到,当我首先搜索“Don”时,UIButton 标签是 100(正确的标签 #)。然后接下来我会搜索“Test”,第一个单元格的 UIButton 标签是 100(应该是 101),第二个单元格的 UIButton 标签是 102(正确)。

当我重新运行应用程序并首先搜索“测试”时,第一个单元格的 UIButton 标记为 101(正确),第二个单元格的 UIButton 标记为 102(正确)。但是当我之后搜索“Don”时,单元格的 UIButton 标签是 101(应该是 100)。

我不确定它是仅在第一个单元格上重叠还是什么,但我在下面提供了我的单元格代码。

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

// register cell identifier from custom cell NIB
static NSString *CellIdentifier = @"FriendCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

// Avatar settings
UIImageView *imvAvatar = [[UIImageView alloc] initWithFrame:CGRectMake(3, 3, 45, 45)];
[imvAvatar setImage:[UIImage imageNamed:@"btnAvatar2.png"]];
imvAvatar.layer.cornerRadius = imvAvatar.frame.size.height/2;
imvAvatar.layer.masksToBounds = YES;
//imvAvatar.layer.borderColor = [UIColor colorWithRed:59/255 green:59/255 blue:121/255 alpha:1].CGColor;
//imvAvatar.layer.borderWidth = 1.0f;

// Befriend Button settings
UIButton *btnBefriend = [[UIButton alloc] initWithFrame:CGRectMake(281, 14, 36, 22)];
[btnBefriend addTarget:self action:@selector(btnBefriendPressed:event:) forControlEvents:UIControlEventTouchUpInside];

// Collect friend info

if (tableView == self.searchDisplayController.searchResultsTableView) 
    friend = [searchResults objectAtIndex:indexPath.section];
 else 
    friend = [arrFriends objectAtIndex:indexPath.section];


NSString *user_id = (NSString *)[friend objectAtIndex:0];    // user id
NSString *username = (NSString *)[friend objectAtIndex:1];   // username
NSString *fName = (NSString *)[friend objectAtIndex:2];      // first name
NSString *lName = (NSString *)[friend objectAtIndex:3];      // last name
NSString *full_name = (NSString *)[friend objectAtIndex:4];  // full name
UIImage *picture = (UIImage *)[friend objectAtIndex:5];      // picture (img)
NSString *type = (NSString *)[friend objectAtIndex:6];       // type
NSString *arrIndex = (NSString *)[friend objectAtIndex:7];   // arrFriends index

// configure cell
if (!cell) 

    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

    // set width depending on device orientation
    cell.frame = CGRectMake(cell.frame.origin.x, cell.frame.origin.y, tableView.frame.size.width, cell.frame.size.height);

    // Name settings
    UILabel *lblName = [[UILabel alloc] initWithFrame:(CGRectMake(60, 3, 215, 45))];
    [lblName setFont:[UIFont systemFontOfSize:14]];

    // Update name, status, picture, befriend button
    lblName.text = full_name;                           // full name
    imvAvatar.image = picture;                          // picture (img)
    if ([type isEqualToString:@""]) 
        [btnBefriend setImage:[UIImage imageNamed:@"btnBefriend.png"] forState:UIControlStateNormal];
    
    else 
        [btnBefriend setImage:[UIImage imageNamed:@"btnBefriended.png"] forState:UIControlStateNormal];
    

    // Cell subviews
    imvAvatar.tag = 1;
    lblName.tag = 2;
    btnBefriend.tag = [arrIndex intValue]+100;
    [cell.contentView addSubview:imvAvatar];
    [cell.contentView addSubview:lblName];
    [cell.contentView addSubview:btnBefriend];
    cell.clipsToBounds = YES;


else 
    // Make sure images, buttons and texts don't overlap

    // avatar
    UIImageView *imvAvatar = (UIImageView *)[cell viewWithTag:1];
    imvAvatar.image = picture;
    // name
    UILabel *lblName = (UILabel *)[cell.contentView viewWithTag:2];
    lblName.text = full_name;
    // befriendbutton
    UIButton *btnBefriend = (UIButton *)[cell.contentView viewWithTag:[arrIndex intValue]+100];
    if ([type isEqualToString:@""]) 
        [btnBefriend setImage:[UIImage imageNamed:@"btnBefriend.png"] forState:UIControlStateNormal];
    
    else 
        [btnBefriend setImage:[UIImage imageNamed:@"btnBefriended.png"] forState:UIControlStateNormal];
    


return cell;

我以为问题出在:

friend = [searchResults objectAtIndex:indexPath.section];
and/or
UIButton *btnBefriend = (UIButton *)[cell.contentView viewWithTag:[arrIndex intValue]+100];

但是出现了正确的图像视图和标签文本,所以我不完全确定是什么导致了这个问题。

非常感谢您的帮助。提前致谢。

【问题讨论】:

这可能与您致电-dequeueReusableCellWithIdentifier:有关。阅读有关该方法的文档。 为什么第二个单元格有正确的标签而不是第一个结果? 我用更多信息编辑了我的答案。 这并没有解决我的问题。自定义单元格会解决这个问题还是我仍然有标签值问题? 【参考方案1】:

您应该使用 avatr 图像和按钮以及所有其他必需的元素创建一个自定义 UITableViewCell,然后重用这个自定义单元格。如果您在- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 中向单元格添加元素,那么只有单元格将被重用,而不是像imvAvatarbtnBefriend 这样您添加到单元格的ui 元素,这些元素将被初始化。这也可能导致内存问题

【讨论】:

我已经考虑过这个选项。这会改变我在搜索结果中的标签值问题吗?还是仅针对内存问题进行此更改? 从搜索结果单元格对象中可以单独获取UI元素,不需要标记元素 每个单元格都像 Facebook 朋友或 Instagram 追随者。我正在标记单元格的按钮,以了解为单击按钮时出现的操作表选择了哪个用户(操作表选项因用户而异)。有没有其他方法可以做到这一点?这是我标记元素的唯一原因。【参考方案2】:

嘿,您可以尝试通过以下方式实现。由于 Cell 是重用的,我们需要在需要时维护 cell 的属性。可以参考以下代码:

这被称为:“将子视图添加到单元格的内容视图”

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
 static NSString *CellIdentifier = @"CellIdentifier";
        UILabel *firstNameLbl, *lastNameLbl ,*userNameLbl ;

        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) 
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

            firstNameLbl = [[UILabel alloc]initWithFrame:CGRectMake(79, 1, 242, 33)];
            firstNameLbl.tag = 500;

            lastNameLbl = [[UILabel alloc]initWithFrame:CGRectMake(79, 30, 241, 20)];
            lastNameLbl.tag = 501;

            userNameLbl = [[UILabel alloc]initWithFrame:CGRectMake(79, 50, 242, 18)];
            musicNarratedByLbl.tag = 502;


            [cell.contentView addSubview: firstNameLbl];
            [cell.contentView addSubview: lastNameLbl];
            [cell.contentView addSubview: userNameLbl];


        else
            firstNameLbl = (UILabel *)[cell.contentView viewWithTag:500];
            lastNameLbl = (UILabel* )[cell.contentView viewWithTag:501];
            userNameLbl = (UILabel *)[cell.contentView viewWithTag:502];

        
 // Here is the code for checking the searchresult controller or normal tableview and apply the data to the lable like as follow;  

if (tableView == self.searchDisplayController.searchResultsTableView)            
       //grab and apply content to each element of Search Results TableView from defined Searche array to each of the lables      

 
else

//grab and apply content to each element of Table view from defined array to each of the lables


return cell;  

更多细节可以参考Apple参考代码sn-p。 在该链接中请参考:清单 5-7 将子视图添加到单元格的内容视图

https://developer.apple.com/library/ios/documentation/userexperience/conceptual/tableview_iphone/TableViewCells/TableViewCells.html

【讨论】:

我在 if (searchrchResultsTableView) 语句中添加了这段代码: btnBefriend.tag = [arrIndex intValue]+100;第一个单元格的按钮标签保持不变。 您只需要在单元重用期间检查此条件。在我的代码片段中写入的方式您只需将标签应用于每个 Ui 对象引用。最后检查表格视图的类型并将值字符串分配给它。我认为它对你有用。请试一试。 在我的代码中,我将 imageview 标签设置为 1,标签标签设置为 2,按钮标签设置为数组中的索引号。搜索结果中的第一个单元格显示正确的图像和标签文本,但不是正确的按钮,即使我更改了 if 语句中的按钮标签。【参考方案3】:

来自 Apple 文档

UITableView

-dequeueReusableCellWithIdentifier:

...

如果现有单元格可供重用,则此方法调用 而是使用单元格的 prepareForReuse 方法。

UITableViewCell

-prepareForReuse

...

tableView:cellForRowAtIndexPath 中的 table view 的委托:应该 重用单元格时始终重置所有内容。

...

编辑 - 更多信息 我没有看到您在代码中明确设置标记值。从 Apple 文档中阅读此内容。也许这就是为什么这些值也不正确的原因。

UIView.tag

默认值为 0。您可以设置此标记的值,然后使用该值来识别视图。

【讨论】:

对不起,我是目标 c 的新手。我需要对我的代码进行哪些更改? 我没有设置您所指的哪个视图?我正在设置标签:imvAvatar.tag = 1; lblName.tag = 2;和 btnBefriend.tag = [arrIndex intValue]+100; 我没有在您的代码中看到该行。将btnBefriend.tag = [arrIndex intValue]+100; 移到if 语句上方,这样每次创建单元格时都会重新配置它,而不是重复使用单元格并且不设置值。 没有解决问题。 自定义单元格会解决这个问题还是我仍然有标签值问题?

以上是关于搜索中的第一个 UITableViewCell UIButton 保持不变的主要内容,如果未能解决你的问题,请参考以下文章

更改 uitableviewcell 文本字段中的第一响应者

将文本移动到 UITableViewCell 中的下一个文本字段

UITableViewController 中的 UITextField

UITableViewCell 中的 UIScrollview 和维护滚动视图页面

如何让 UIImageView 填充 UITableViewCell?

UITableViewCell 中的最终 UIButton 是不可变的