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
相关产品推荐
相关产品推荐

