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

Swift开发:如何在不同Table View场景下加载多份JSON数据

页面空白的直接原因

  • 你的DetailViewController继承的是UIViewController而非UITableViewController,没有内置的tableView实例,你也没有手动创建tableView,反而将根视图设置为WKWebView,写的tableView数据源、代理方法没有绑定触发对象,自然不会展示内容。
  • 解析完meals数组后没有调用视图刷新方法,就算有tableView也不会更新内容。
  • 跳转详情页时没有传递选中的分类参数,详情页写死仅请求Beef分类的数据,无法适配不同分类的请求需求。

疑问解答

1、需要为每份JSON分别创建3个不同的Table View吗?还是仅用1个就足够?

不需要单独创建3个,1个即可。只要给视图控制器设置对应类型的数据源数组,请求对应接口更新数组后刷新tableView就能复用。只有当3份JSON的数据结构差异极大、单元格展示样式完全不同时,才需要考虑分开创建不同的视图控制器或者自定义不同的单元格。

2、处理JSON数据时,是否需要使用类似“prepare”的专用函数来预处理即将展示的新JSON?

不需要专门的预处理函数,如果你是通过上级页面跳转传递参数,才需要用到prepare(for segue:)方法给下一级页面传参(比如选中的分类名称,用来给详情页拼接请求接口参数)。JSON的解析逻辑你可以单独封装成方法,在拿到接口返回数据后调用即可,没有强制要求必须用特定系统函数处理。


修改方案

第一步:修改DetailViewController配置

import UIKit

class DetailViewController: UITableViewController {
    // 接收上级传递的分类名,用于拼接请求地址
    var categoryName: String!
    var meals = [Meal]()

    override func viewDidLoad() {
        super.viewDidLoad()
        // 注册单元格,确保标识符对应
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
        
        let urlString = "https://www.themealdb.com/api/json/v1/1/filter.php?c=\(categoryName ?? "Beef")"
        
        if let url = URL(string: urlString) {
            // 改成异步请求避免卡住主线程
            DispatchQueue.global().async {
                if let data = try? Data(contentsOf: url) {
                    self.parse(json: data)
                } else {
                    print("连接错误")
                }
            }
        }
    }
    
    func parse(json: Data) {
        let decoder = JSONDecoder()
        do {
            let jsonMeals = try decoder.decode(Meals.self, from: json)
            meals = jsonMeals.meals
            // 回到主线程刷新列表
            DispatchQueue.main.async {
                self.tableView.reloadData()
            }
        } catch {
            print("解析错误: \(error)")
        }
    }
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return meals.count
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        let meal = meals[indexPath.row]
        cell.textLabel?.text = meal.idMeal
        cell.detailTextLabel?.text = meal.strMeal
        return cell
    }
}

第二步:修改ViewController跳转逻辑

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let newViewController = DetailViewController()
    // 传递选中的分类名到详情页
    newViewController.categoryName = categories[indexPath.row].strCategory
    self.navigationController?.pushViewController(newViewController, animated: true)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 21:36:01