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

如何在UITableView中逐个显示嵌套API响应对象并切换节点

嵌套树形API响应的UITableView节点切换问题

已成功遍历到第一个嵌套API响应数组的末尾,但无法切换到下一个节点(例如从id为865的问题切换到id为866的问题)。尝试通过DFS遍历将JSON转为字典、参考CollectionView切换方案均无效,当前代码无法正确处理嵌套树形结构,需要实现在UITableView中逐个展示这些API响应对象并完成节点切换。

现有代码

DFS遍历代码

func preorderTraversalDFS(_ roots: [ResultsQuestions]?) -> [Int: TreeItem] { // Get the json response in dictionary
        guard let roots = roots else {
            return [:]
        }
        
        var result: [Int: TreeItem] = [:]
        
        for root in roots {
            let treeItem = TreeItem(id: root.id,
                                    title: root.title,
                                    description: root.description,
                                    type: root.type,
                                    assessment: root.assessment,
                                    choices: convertChoices(root.choices),
                                    choice: root.choice,
                                    creator: root.creator)
            result[root.id] = treeItem
            if let choices = root.choices {
                for choice in choices {
                    let subTree = preorderTraversalDFS(choice.questions)
                    subTree.forEach { (key, value) in
                        result[key] = value
                    }
                }
            }
        }
        arrayDict = result
        return result
    }

UITableView代理与数据源代码

extension viewController : UITableViewDelegate , UITableViewDataSource {
    
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return objResponseQuestions.count // decoded json stored in objResponseQuestions
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

            guard let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: nestedAssessmentTableViewCell.self), for: indexPath) as? nestedAssessmentTableViewCell else { return nestedAssessmentTableViewCell() }
            cell.selectionStyle = UITableViewCell.SelectionStyle.none

            cell.optionsLabel.text = objResponseQuestions?[indexPath.row].choices?[indexPath.row].title
                       
            return cell
}
}

数据结构定义

// MARK: - Choice
struct Choice: Codable {
    let id: Int
    let title: String
    let nasClass: String
    let question: Int
    let questions: [ResultsQuestions]?

    enum CodingKeys: String, CodingKey {
        case id, title
        case nasClass = "nasClass"
        case question, questions
    }
}

// MARK: - Result
struct ResultsQuestions: Codable {
    let id: Int
    let title, description, type: String
    let assessment: Int
    let choices: [Choice]?
    let choice: Int?
    let creator: Int
} // This is the data strut I have loaded my json response into 

问题根源

  1. DFS遍历丢失树形关联:将所有节点存入字典后,无法追踪「选择某个选项后跳转至对应子节点」的关联关系,仅能获取孤立的节点数据。
  2. UITableView数据源未动态更新:直接使用原始的objResponseQuestions作为数据源,无法根据用户的选择切换到下一层节点的内容。

解决方案

1. 维护当前节点与路径

在ViewController中添加变量记录当前展示的问题节点,以及路径(用于回退场景):

// 当前正在展示的问题节点
var currentQuestion: ResultsQuestions?
// 问题路径栈,用于回退到上一层(可选)
var questionPath: [ResultsQuestions] = []

2. 初始化初始节点

在视图加载完成后,设置初始展示的根节点:

override func viewDidLoad() {
    super.viewDidLoad()
    // 假设objResponseQuestions是根节点数组,取第一个作为初始节点
    if let firstQuestion = objResponseQuestions?.first {
        currentQuestion = firstQuestion
        questionPath.append(firstQuestion)
        tableView.reloadData()
    }
}

3. 修改UITableView代理与数据源

基于当前节点动态展示选项,并处理点击跳转逻辑:

extension ViewController: UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // 行数为当前节点的选项数量
        return currentQuestion?.choices?.count ?? 0
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: NestedAssessmentTableViewCell.self), for: indexPath) as? NestedAssessmentTableViewCell else {
            return NestedAssessmentTableViewCell()
        }
        cell.selectionStyle = .none
        // 展示当前节点对应索引的选项标题
        cell.optionsLabel.text = currentQuestion?.choices?[indexPath.row].title
        return cell
    }

    // 处理选项点击,切换到下一层节点
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        guard let selectedChoice = currentQuestion?.choices?[indexPath.row],
              let nextQuestions = selectedChoice.questions,
              let nextQuestion = nextQuestions.first else {
            // 无下一层节点时的逻辑(比如结束流程)
            return
        }
        // 更新当前节点并记录路径
        currentQuestion = nextQuestion
        questionPath.append(nextQuestion)
        // 刷新表格展示新节点的选项
        tableView.reloadData()
    }
}

4. 可选:添加回退功能

如果需要支持返回上一层问题,可以添加按钮触发以下逻辑:

@IBAction func backButtonTapped(_ sender: UIButton) {
    guard questionPath.count > 1 else {
        // 已经是根节点,无法回退
        return
    }
    // 移除当前节点,回到上一层
    questionPath.removeLast()
    currentQuestion = questionPath.last
    tableView.reloadData()
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 13:12:32