首页 > 解决方案 > 通过Alamofire,想获取数据并将其插入TableView,但在插入完成之前,TableView被加载

问题描述

正如我在标题上写的那样,我正在使用Alamofire获取数据然后对其进行解码并将其附加到列表“articleList”然后尝试将其插入TableView,但似乎首先加载了TableView,并且然后收集数据并将其插入到列表中。我想先插入,然后加载 TableView 但我找不到解决方案。我只是通过将 defer 放入 viewDidLoad 并制作 tableView.realodData 来尝试它,但它不起作用......有人可以给我任何关于这种情况的想法吗?

import UIKit
import Alamofire

class NewsViewController: UITableViewController {
    var urlForApi = "https://newsapi.org/v2/top-headlines?country=jp&category=technology&apiKey=..."

    var articleList = [Article]()

    override func viewDidLoad() {
        super.viewDidLoad()
        updateNewsData()
        defer {
            tableView.reloadData()
        }
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print(articleList.count)
        return articleList.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

        cell.textLabel?.text = articleList[indexPath.row].title

        return cell
    }

    //    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    //
    //    }

    func updateNewsData() {
        getNewsData() { (articles) in
            guard let articleArray = articles?.articles else
            {fatalError("cannot get articles.")}

            for article in articleArray {
                self.articleList.append(article)
            }

            print("insert is done")
        }
    }

    func getNewsData(completion: @escaping (ArticlesListResult?) -> Void) {
        Alamofire.request(urlForApi, method: .get)
            .responseJSON { response in
                if response.result.isSuccess {
                    if let data = response.data {
                        let articles = try? JSONDecoder().decode(ArticlesListResult.self, from: data)
                        completion(articles)
                    }
                } else {
                    print("Error: \(String(describing: response.result.error))")
                }
        }
    }
}

标签: iosswiftuitableviewalamofire

解决方案


Instead of writing tableView.reloadData() in viewDidLoad method, you should write it after you complete appending all articles in the articleList array.

Sample code:

viewDidLoad() should be like:

override func viewDidLoad() {
    super.viewDidLoad()
    updateNewsData()
}

updateNewsData() should be like:

func updateNewsData() {
    getNewsData() { (articles) in
        guard let articleArray = articles?.articles else
        {fatalError("cannot get articles.")}

        articleList.append(contentsOf: articleArray)
        DispatchQueue.main.async {
            tableView.reloadData()
        }
    }
}

推荐阅读