You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UITableView折叠展开后按钮选中状态未正确恢复问题求助

问题分析与解决方案

你的核心问题在于单元格复用过程中,按钮状态设置没有作用到正确的Cell上。在cellForRowAtIndexPath里调用setHalfButton:/setFullButton:时,你用[comboTableView cellForRowAtIndexPath:indexPath]获取Cell,但此时当前Cell还处于配置阶段,尚未被添加到TableView的可视区域,这个方法可能返回nil或者不是你正在配置的那个Cell,导致样式设置完全无效。

下面是具体的修复步骤:


1. 重构按钮状态配置方法

将原来依赖NSIndexPath获取Cell的方法,改为直接接收ComboTableViewCell作为参数,这样可以确保操作的是当前正在配置的Cell:

-(void)configureHalfButtonForCell:(ComboTableViewCell*)cell {
    [cell.halfBtnOutlet setTitleColor:[UIColor colorWithRed:0 green:102.0f/255.0f blue:0 alpha:1] forState:UIControlStateNormal];
    [cell.fullBtnOutlet setTitleColor:[UIColor colorWithRed:0.5f green:0.5f blue:0.5f alpha:1] forState:UIControlStateNormal];
    [cell.halfBtnOutlet.titleLabel setFont:[UIFont boldSystemFontOfSize:15.f]];
    [cell.fullBtnOutlet.titleLabel setFont:[UIFont systemFontOfSize:15.f]];
}

-(void)configureFullButtonForCell:(ComboTableViewCell*)cell {
    [cell.fullBtnOutlet setTitleColor:[UIColor colorWithRed:0 green:102.0f/255.0f blue:0 alpha:1] forState:UIControlStateNormal];
    [cell.halfBtnOutlet.setTitleColor:[UIColor colorWithRed:0.5f green:0.5f blue:0.5f alpha:1] forState:UIControlStateNormal];
    [cell.fullBtnOutlet.titleLabel setFont:[UIFont boldSystemFontOfSize:15.f]];
    [cell.halfBtnOutlet.titleLabel setFont:[UIFont systemFontOfSize:15.f]];
}

2. 修复cellForRowAtIndexPath配置逻辑

在Cell配置时,直接传入当前Cell到新的配置方法中,同时增加状态重置步骤,避免Cell复用带来的旧样式残留:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *cellIdentifier = @"ComboCell";
    ComboTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell == nil) {
        cell = [[ComboTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
        // 把按钮Target添加移到这里,避免重复绑定事件(关键优化)
        [cell.halfBtnOutlet addTarget:self action:@selector(halfBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
        [cell.fullBtnOutlet addTarget:self action:@selector(fullBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
    }

    // 先重置所有状态,避免复用旧Cell的残留样式
    cell.halfBtnOutlet.hidden = YES;
    cell.fullBtnOutlet.hidden = YES;
    cell.accessoryType = UITableViewCellAccessoryNone;

    if([selectedRowsInSectionDictionary[@(indexPath.section)] containsObject: indexPath]) {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
        cell.halfBtnOutlet.hidden = NO;
        cell.fullBtnOutlet.hidden = NO;

        if( comboItemsArray[indexPath.section].allComboItems[indexPath.row].pQuantity == 0.5) {
            [self configureHalfButtonForCell:cell];
        } else {
            [self configureFullButtonForCell:cell];
        }
    }

    cell.comboTitle.text = comboItemsArray[indexPath.section].allComboItems[indexPath.row].pName;
    return cell;
}

3. 额外优化:避免重复绑定按钮事件

原来的代码每次配置Cell都给按钮添加Target,会导致同一个按钮被多次绑定相同事件,点击时触发多次响应。上面的修复已经把Target添加移到Cell初始化分支里,确保每个Cell只绑定一次事件。如果你的Cell是从XIB/Storyboard加载的,可以把Target绑定移到Cell的awakeFromNib方法中:

// ComboTableViewCell.m
- (void)awakeFromNib {
    [super awakeFromNib];
    [self.halfBtnOutlet addTarget:self.delegate action:@selector(halfBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
    [self.fullBtnOutlet addTarget:self.delegate action:@selector(fullBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
}

同时记得给Cell添加一个delegate属性,在ViewController的cellForRowAtIndexPath里设置cell.delegate = self。


这样修改后,当你重新加载Section时,Cell会根据comboItemsArray里保存的pQuantity值,正确渲染按钮的选中状态,不会再出现重置为默认值的问题。

内容的提问来源于stack exchange,提问作者casillas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:49:07