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

Swift 4中如何展示JSON的嵌套子数据?

在Swift 4中展示JSON嵌套子数据的实现方案

嘿,看起来你已经搞定了第一层TableView的展示,接下来要处理嵌套的clothe数据对吧?我给你两种常用的实现思路,你可以根据产品需求来选:


方案一:点击Cell跳转到详情TableView展示子数据

这是最常见的做法,用户点击第一层的杂志Cell,进入新页面查看该杂志对应的服饰列表。

步骤说明:

  1. 确保数据源就绪:你应该已经有一个存储解析后数据的数组,比如:

    var heroStatsArray: [HeroStats] = []
    // 解析JSON后填充这个数组的代码你应该已经写好了,这里就不重复啦
    
  2. 实现第一个TableView的点击事件:
    在didSelectRowAt方法里,获取选中的杂志数据,判断是否有子数据,然后跳转:

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        let selectedMagazine = heroStatsArray[indexPath.row]
        // 先判断是否有服饰数据
        guard let clothes = selectedMagazine.clothe, !clothes.isEmpty else {
            // 没有数据可以提示用户,或者啥也不做
            return
        }
        // 创建详情页控制器
        let detailVC = ClothesTableViewController()
        detailVC.clothesData = clothes
        // 导航跳转(如果是导航控制器的话)
        navigationController?.pushViewController(detailVC, animated: true)
        // 如果是模态跳转用这个:present(detailVC, animated: true)
    }
    
  3. 实现详情页TableView:
    新建一个ClothesTableViewController,定义数据源并实现TableView代理方法:

    class ClothesTableViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
        var clothesData: [SecondTable] = []
        private let tableView = UITableView()
    
        override func viewDidLoad() {
            super.viewDidLoad()
            title = "服饰列表"
            // 这里记得给tableView添加约束或者设置frame
            tableView.dataSource = self
            tableView.delegate = self
            tableView.register(UITableViewCell.self, forCellReuseIdentifier: "ClotheCell")
        }
    
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return clothesData.count
        }
    
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "ClotheCell", for: indexPath)
            let clothe = clothesData[indexPath.row]
            cell.textLabel?.text = clothe.nameClothe
            // 加载图片:如果是本地图片用UIImage(named:),网络图片可以用Kingfisher这类库
            cell.imageView?.image = UIImage(named: clothe.imageClothe)
            return cell
        }
    }
    

方案二:在同一个TableView中实现折叠/展开效果

如果不想跳转页面,想在同一个TableView里通过展开/折叠来展示子数据,可以用分组TableView的方式实现:

步骤说明:

  1. 添加展开状态记录数组:
    用来记录每个杂志组是否处于展开状态:

    var heroStatsArray: [HeroStats] = []
    var expandedSections: [Bool] = [] // 每个元素对应一个组的展开状态
    
    // 解析完JSON后初始化这个数组
    func setupExpandedStatus() {
        expandedSections = Array(repeating: false, count: heroStatsArray.count)
    }
    
  2. 修改TableView的分组和行数逻辑:

    // 分组数等于杂志的数量
    func numberOfSections(in tableView: UITableView) -> Int {
        return heroStatsArray.count
    }
    
    // 每组的行数:展开状态下显示子数据数量,否则0
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        guard expandedSections[section] else { return 0 }
        return heroStatsArray[section].clothe?.count ?? 0
    }
    
    // 自定义Header,用来点击切换展开状态
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let headerView = UIView()
        headerView.backgroundColor = .lightGray
        // 添加标题Label
        let titleLabel = UILabel(frame: CGRect(x: 16, y: 0, width: view.frame.width - 32, height: 44))
        titleLabel.text = heroStatsArray[section].name
        headerView.addSubview(titleLabel)
        // 添加点击手势
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(toggleSection(_:)))
        headerView.addGestureRecognizer(tapGesture)
        return headerView
    }
    
    // 切换展开状态的方法
    @objc func toggleSection(_ gesture: UITapGestureRecognizer) {
        guard let headerView = gesture.view else { return }
        let section = tableView.indexPath(for: headerView)?.section ?? 0
        expandedSections[section] = !expandedSections[section]
        // 刷新当前组的行
        tableView.reloadSections(IndexSet(integer: section), with: .automatic)
    }
    
  3. 实现Cell的内容展示:

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "ClotheCell", for: indexPath)
        let clothe = heroStatsArray[indexPath.section].clothe?[indexPath.row]
        cell.textLabel?.text = clothe?.nameClothe
        cell.imageView?.image = clothe.map { UIImage(named: $0.imageClothe) } ?? nil
        return cell
    }
    

注意事项:

  • 因为你的clothe是可选数组,所以所有用到它的地方都要做nil判断,避免崩溃;
  • 图片加载如果是网络地址,建议用Kingfisher或者SDWebImage这类第三方库来处理缓存和异步加载;
  • 记得给TableView注册Cell,或者用xib自定义Cell来优化展示效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:23:59