首页 > 解决方案 > 如何使用 JSON 数据填充自定义 UITableViewCell?

问题描述

我一直在用 swift 5 练习网络,但我似乎总是卡在将 json 解析为 UITableViewCells。我看过很多教程,但似乎无法找出问题所在。我要做的是检索国家名称并将其放在表格视图单元格中。

我使用这个 url 来请求 json:https ://restcountries.eu/rest/v2/

视图模型:

struct Countries: Codable {
    let name: String?
    let capital: String?
    let region: String?
    let population: String?
    let currencies: [Currency]?
    let languages: [Language]?
    let flag: URL?
}

struct Currency: Codable {
    let code: String?
    let name: String?
    let symbol: String?
}

struct Language: Codable {
    let name: String?
}

我的 API 请求:

class Service {
    static let shared = Service()
    
    func fetchCountriesData(completed: @escaping (Result<Countries, ErrorMessages>) -> Void) {
        
        let urlString = "https://restcountries.eu/rest/v2/"
        
        guard let url = URL(string: urlString) else { return }
        
        let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
            // error
            if let _ = error {
                completed(.failure(.invalidData))
                return
            }
            
            // response
            guard let response = response as? HTTPURLResponse, response.statusCode == 200 else {
                completed(.failure(.invalidResponse))
                return
            }
            
            // data
            guard let data = data else {
                completed(.failure(.invalidData))
                return
            }
            
            do {
                let decoder = JSONDecoder()
                //decoder.keyDecodingStrategy = .convertFromSnakeCase
                let results = try decoder.decode(Countries.self, from: data)
                completed(.success(results))
            } catch {
                completed(.failure(.invalidData))
            }
        }
        task.resume()
    }
}

我的主视图控制器:

class MainViewController: UITableViewController {
    
    var cellId = "cellId"
    var countryData =  [Countries]()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        style()
        tableView.delegate = self
        tableView.dataSource = self
    }
    func style() {
        navigationItem.title = "Search country information"
        tableView.register(CountryViewCell.self, forCellReuseIdentifier: cellId)
        //tableView.separatorStyle = .none
    }
}

extension MainViewController {
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as? CountryViewCell else {
            return UITableViewCell()
        }
        let results = countryData[indexPath.row].name
        cell.titleLabel.text = results
        return cell
        
    }
}

以及自定义的 TableViewCell:

class CountryViewCell: UITableViewCell {
    
    private var countryResults: Countries? {
        didSet {
            self.titleLabel.text = countryResults?.name
        }
    }
    
    var titleLabel: UILabel = {
        let label = UILabel()
        label.text = "countries"
        label.font = .boldSystemFont(ofSize: 16)
        label.numberOfLines = 0
        label.textColor = .black
        return label
    }()
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        configure()
        layout()
        //displayResults()
        
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

extension CountryViewCell {
    func configure() {
        selectionStyle = .gray
        titleLabel.translatesAutoresizingMaskIntoConstraints = false
    }
    func layout() {
        addSubview(titleLabel)
        
        NSLayoutConstraint.activate([
            titleLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 20),
            titleLabel.heightAnchor.constraint(equalToConstant: 20),
            titleLabel.centerYAnchor.constraint(equalTo: centerYAnchor),
        ])
    }
}

标签: uitableviewswift5ios14

解决方案


推荐阅读