如何将API获取的JSON数据展示到TableView的自定义单元格中
调整步骤
- 给
MainVC添加数据源数组,同时设置tableView的代理和数据源绑定 - 调整API请求方法,拿到数据后赋值给数据源并回到主线程刷新列表
- 完善TableView数据源方法,将数据绑定到自定义单元格
- 给自定义单元格添加数据配置方法,处理文本赋值和网络图片加载
1. 修改MainVC代码
import UIKit class MainVC: UIViewController { @IBOutlet weak var tableView: UITableView! // 新增数据源数组 var catBreeds: [Breed] = [] override func viewDidLoad() { super.viewDidLoad() title = "Cats" view.backgroundColor = .systemBackground // 绑定tableView代理和数据源 tableView.delegate = self tableView.dataSource = self getDataFromCatsApi() } // 调整API请求方法,支持数据回调刷新 func getDataFromCatsApi() { guard let url = URL(string: "https://api.thecatapi.com/v1/breeds") else { return } let task = URLSession.shared.dataTask(with: url) { [weak self] data, _ , error in guard let self = self else { return } if let error = error { print(error) return } guard let data = data else { return } let decoder = JSONDecoder() if let breedList = try? decoder.decode([Breed].self, from: data) { // 赋值给数据源 self.catBreeds = breedList // 回到主线程刷新UI DispatchQueue.main.async { self.tableView.reloadData() } } } task.resume() } } extension MainVC: UITableViewDelegate, UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // 行数和数据源数量保持一致 return catBreeds.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { guard let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? CustomTableViewCell else { return UITableViewCell() } let currentBreed = catBreeds[indexPath.row] // 调用单元格配置方法传入数据 cell.configure(with: currentBreed) return cell } }
2. 修改CustomTableViewCell代码
import UIKit class CustomTableViewCell: UITableViewCell { @IBOutlet weak var catImageView: UIImageView! @IBOutlet weak var nameLabel: UILabel! @IBOutlet weak var originLabel: UILabel! @IBOutlet weak var addToFavButton: UIButton! } // 新增配置方法 extension CustomTableViewCell { func configure(with breed: Breed) { nameLabel.text = breed.name ?? "未知品种" originLabel.text = breed.origin ?? "未知产地" // 先设置占位图,可自行替换为项目内的占位资源 catImageView.image = UIImage(named: "placeholder") guard let imageUrlStr = breed.image?.url, let imageUrl = URL(string: imageUrlStr) else { return } // 异步加载网络图片避免卡主线程 DispatchQueue.global().async { if let imageData = try? Data(contentsOf: imageUrl), let image = UIImage(data: imageData) { DispatchQueue.main.async { self.catImageView.image = image } } } } }
注意事项
- 请确认Storyboard中自定义单元格的重用ID设置为
cell,与代码中的重用ID保持一致 - 如果需要优化列表滑动体验、避免图片重复加载,可引入Kingfisher、SDWebImage等第三方图片库处理图片加载逻辑
内容的提问来源于stack exchange,提问作者Andy
相关产品推荐
相关产品推荐

