UITableView 在单元格选择上更改图像并重置其他图像

Posted

技术标签:

【中文标题】UITableView 在单元格选择上更改图像并重置其他图像【英文标题】:UITableView change image on cell select and reset others 【发布时间】:2014-01-31 15:22:22 【问题描述】:

当用户选择该行时,我想更改 UITableViewCell 内的 UIImage。现在太难了。我可以在didSelectRowAtIndex 中做到这一点。但是,问题出在这里,我希望其他单元格(每个 cell 都有标准图像)再次拥有标准图像。 (如果单元格再次有标准图像,则选择的图像应该被“标记”(意思是未标记的图像将被标记的图像替换,我已经有代码了)

将其视为您从html 知道的Checkbox

这是我的尝试:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
    [tableView cellForRowAtIndexPath:indexPath];
    [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:YES];

    //Little flashing animation
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    [UIView animateWithDuration:2.0f animations:^

     completion:^(BOOL finished) 
        ;
    ];

    //Mark the selected cell
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    ALog(@"%i", cell.imageView.tag);
    ALog(@"%i", [[[tableView cellForRowAtIndexPath:indexPath] imageView] tag]);

    UIImageView *iconimgView = (UIImageView *)[[tableView cellForRowAtIndexPath:indexPath] viewWithTag:TAG_IMAGEMARKERCELL];
    [iconimgView setImage:[UIImage imageNamed:@"circle-answer-marked.png"]];

    //..

UIImageView 在这里定义:

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

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) 
        //Add this to cell only once, not everytime a cell is displayed! (Everyhing goes in here)
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
        [[cell textLabel] setNumberOfLines:0]; // unlimited number of lines
        [[cell textLabel] setLineBreakMode:NSLineBreakByWordWrapping];
        [[cell textLabel] setFont:[UIFont fontWithName:@"PTSans-Regular" size:33 / 2]];
        [[cell textLabel] setTextColor:[self colorFromHexString:COLOR_DEFAULT_TEXT_COLOR]];
        cell.indentationLevel = cell.indentationLevel + 2;

        //        //Marker image
        imgCell_Marker = [[UIImageView alloc]initWithFrame:CGRectMake(10, 22, 20, 20)];
        imgCell_Marker.image=[UIImage imageNamed:@"circle-answer.png"];
        imgCell_Marker.tag = TAG_IMAGEMARKERCELL;
        ALog(@"%@", imgCell_Marker);
        [cell.contentView addSubview:imgCell_Marker];
    

        //..
        return cell;

奇怪的是,UIImageViews 有一个预定义的tag,但如果我想在didSelectRowAtIndexPath 中得到它,它总是“0”。 (tag的默认值)

提前致谢。

【问题讨论】:

【参考方案1】:

使用这段代码:

-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
   
    [tableView reloadData];
    UITableViewCell *cell = (UITableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
    cell.imageView.image = [UIImage imageNamed:@"image.png"];

首先,您将所有单元格设置为默认状态,然后更改当前单元格的图像。

【讨论】:

这什么也没做。我什至尝试在if(cell == nil) 之外重写UIImageView 如果要将图像添加到单元格中,请为 UITableViewCell 创建自定义类。比代码可以工作。遵循本教程:appcoda.com/customize-table-view-cells-for-uitableview 用你的答案和 Wain 解决了这个问题。谢谢。 :) 感谢真棒回答!我正在寻找一种方法来获取选定的单元格【参考方案2】:

您在多个方面都有问题。

首先,确定应该显示什么图像的信息应该是模型的一部分。 So, when a row is selected, set a flag in your model to say that this item is tagged.同时,找到其他被标记的项目并取消标记它们。现在,重新加载已更改的行。在cellForRowAtIndexPath 中,根据模型中的标签信息更新请求的单元格以设置标准或替代图像。

其次,对于您使用tag - 您在imgCell_MarkerimageView 之间混淆了。当你这样做时:

ALog(@"%i", [[[tableView cellForRowAtIndexPath:indexPath] imageView] tag]);

您正在查询默认的imageView,因此tag 将始终为零。您应该使用viewWithTag:TAG_IMAGEMARKERCELL 来找到您想要的实际图像视图。

【讨论】:

感谢 ALog 的提示。我知道从tag 获得正确的值。 您需要确保图像始终设置为正确的值。目前单元重用会破坏你的代码。您需要重新考虑您的方法并更新您的数据模型。 我解决了这个问题。所以我不得不远程 if 语句if(cell == nil) 在我的情况下。 (无论如何它都会重建单元格)然后在didSelectRowAtIndexPath 中调用[tableView reloadData]。谢谢。我希望我的投票会否定你的-1。 :)【参考方案3】:

从属性检查器中,将您的原型单元的附件设置为“复选标记”。这将解决您的问题。无需更改图像或任何东西。如果这不是你想要的,请告诉我

【讨论】:

我需要使用自定义图像。所以内置的 CheckMark 功能不会为我做这件事。谢谢你。【参考方案4】:

让您生活轻松。使用 UITableViewCell::selectedBackgroundView 预先设置选定单元格的内容。

【讨论】:

这对我有什么帮助?我必须从 Cell 切换整个视图(可见部分)?能不能说的具体点? 您可以将 UIView 附加到 backgroudnView。当 didSelectCell 被调用时,将显示 backgroundView。这是让单元格在选中时具有完全不同的内容/布局的好方法。另一种方法是继承 UITableViewCell 并覆盖 setSelected:animate: 方法。【参考方案5】:

注意:这在我的情况下是完美的,所以你可能不想在你的情况下使用它(或者让我解释一下为什么当你和我处于相似位置时你应该这样做)

现在的代码应该是这样的:

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

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    [[cell textLabel] setNumberOfLines:0]; // unlimited number of lines
    [[cell textLabel] setLineBreakMode:NSLineBreakByWordWrapping];
    [[cell textLabel] setFont:[UIFont fontWithName:@"PTSans-Regular" size:33 / 2]];
    [[cell textLabel] setTextColor:[self colorFromHexString:COLOR_DEFAULT_TEXT_COLOR]];
    cell.indentationLevel = cell.indentationLevel + 2;

    //Marker image
    imgCell_Marker = [[UIImageView alloc]initWithFrame:CGRectMake(10, 22, 20, 20)];
    imgCell_Marker.image=[UIImage imageNamed:@"circle-answer.png"];
    imgCell_Marker.tag = TAG_IMAGEMARKERCELL;
    [cell.contentView addSubview:imgCell_Marker];

    //.. (more data here, just snipped it)
    return cell;

这就是我使用它的原因:

我知道 UITableView 的数据来自我的数组只有前 5 个项目长。因此,我可以简单地删除 UITableViewcellForRowAtIndexPath 方法中的 if 语句。它不会伤害我的应用程序(或浪费 cpu 时间),因为要做的事情很少,不知道会知道。

不过,这个解决方案有点难看。但在这种情况下还可以(我猜)

【讨论】:

以上是关于UITableView 在单元格选择上更改图像并重置其他图像的主要内容,如果未能解决你的问题,请参考以下文章

选择单元格时更改图像

更改长按 uiTableView IOS 上的单元格选择

动态更改 UITableView 单元格中 UIButton 的图像

UITableView 将所做的更改应用于每个第 n 个单元格

选择后更改表格视图单元格?

更改自定义单元格中按钮的图像