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

UITableView内嵌UICollectionView:选中状态传递与行显隐处理问询

解决方案:传递选中事件并控制TableView行显隐

嘿,我来帮你搞定这个问题!核心就是要让内嵌UICollectionView的TableViewCell,把选中的答案传递给TableView所在的ViewController,然后由VC判断哪些行需要隐藏,最后刷新TableView生效。下面是两种最实用的实现方式:

方案一:用闭包传递选中事件(推荐,简单直接)

步骤1:修改内嵌CollectionView的TableViewCell

首先找到你的那个带UICollectionView的TableViewCell类(比如你代码里的FormExpenseTypeCell或者对应typeId的目标cell),给它添加一个闭包属性,用来传递选中的答案:

// 替换成你实际的cell类名,比如FormExpenseTypeCell
class YourCollectionEmbeddedCell: UITableViewCell {
    // 你已有的属性:optionsCollectionView、selectedItem等
    var selectedItem: String?
    
    // 添加闭包属性,用于传递选中结果
    var onOptionSelected: ((String?) -> Void)?
    
    // 你的collectionView选中方法修改如下
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        guard let cell = collectionView.cellForItem(at: indexPath) as? OptionsCollectionViewCell else { return }
        let selectedText = cell.itemButton.titleLabel?.text
        selectedItem = selectedText
        
        // 调用闭包,把选中的值传出去
        onOptionSelected?(selectedText)
    }
}

步骤2:在ViewController中接收事件并控制行显隐

在你的cellForRowAt方法里,初始化目标cell时设置闭包,处理选中后的逻辑,同时维护一个变量记录是否需要隐藏目标行:

// 在ViewController里添加变量,记录是否隐藏问题3
private var shouldHideQuestion3 = false

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if sortedFixedContentType.count != 0 {
        let item = sortedFixedContentType[indexPath.row]
        switch item.typeId {
        // 保留你其他case的代码不变
        case "39": // 假设这个是带CollectionView的cell对应的typeId
            let cell = tableView.dequeueReusableCell(withIdentifier: "FormExpenseTypeCell", for: indexPath) as! FormExpenseTypeCell
            
            // 设置闭包,处理选中事件
            cell.onOptionSelected = { [weak self] selectedAnswer in
                guard let self = self else { return }
                
                // 这里根据实际逻辑判断:比如当前cell是问题2,选中"No"则隐藏问题3
                if indexPath.row == 1 { // 替换成你问题2的实际行索引或判断条件
                    self.shouldHideQuestion3 = (selectedAnswer == "No")
                    // 刷新TableView,让行显隐生效
                    self.tableView.reloadData()
                }
            }
            return cell;
        // 其他case代码不变
        default:
            let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath) as! BaseFormCell
            cell.idLabel.text = item.htmlType
            return cell
        }
    } else {
        let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath) as! BaseFormCell
        cell.idLabel.text = ""
        return cell
    }
}

步骤3:控制行的显隐

实现heightForRowAt方法,根据shouldHideQuestion3的值控制目标行的高度:

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    // 判断是否是需要隐藏的行(比如问题3的行)
    if indexPath.row == 2 && shouldHideQuestion3 { // 替换成问题3的实际行索引
        return 0 // 高度设为0实现隐藏
    }
    // 其他行返回自动高度或固定高度
    return UITableView.automaticDimension
}

或者你也可以用willDisplay方法设置cell的isHidden属性:

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    if indexPath.row == 2 && shouldHideQuestion3 {
        cell.isHidden = true
    } else {
        cell.isHidden = false
    }
}

方案二:用代理模式传递事件(适合复杂场景)

如果你的表单有多个类似的依赖问题,代理模式会更清晰:

步骤1:定义代理协议

protocol OptionSelectionDelegate: AnyObject {
    func didSelectOption(_ option: String?, from cell: UITableViewCell)
}

步骤2:修改TableViewCell添加代理属性

class YourCollectionEmbeddedCell: UITableViewCell {
    weak var delegate: OptionSelectionDelegate?
    var selectedItem: String?
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        guard let cell = collectionView.cellForItem(at: indexPath) as? OptionsCollectionViewCell else { return }
        let selectedText = cell.itemButton.titleLabel?.text
        selectedItem = selectedText
        
        // 通知代理
        delegate?.didSelectOption(selectedText, from: self)
    }
}

步骤3:ViewController遵守代理协议

class YourViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, OptionSelectionDelegate {
    private var shouldHideQuestion3 = false
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        // ...其他代码不变
        case "39":
            let cell = tableView.dequeueReusableCell(withIdentifier: "FormExpenseTypeCell", for: indexPath) as! FormExpenseTypeCell
            cell.delegate = self // 设置代理
            return cell
        // ...其他代码
    }
    
    // 实现代理方法
    func didSelectOption(_ option: String?, from cell: UITableViewCell) {
        guard let indexPath = tableView.indexPath(for: cell) else { return }
        
        // 判断当前cell对应的问题,比如问题2
        if indexPath.row == 1 {
            shouldHideQuestion3 = (option == "No")
            tableView.reloadData()
        }
    }
}

额外提示

  • 用[weak self]避免循环引用,防止内存泄漏
  • 如果有多个依赖问题,建议维护一个字典(比如[String: String])来记录每个问题的选中答案,key可以用问题的typeId或者索引,这样判断行显隐时更灵活
  • 刷新TableView时,也可以用reloadRows(at:with:)只刷新需要变化的行,提升性能:
    tableView.reloadRows(at: [IndexPath(row: 2, section: 0)], with: .automatic)
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 06:32:23