集合视图不显示数据

Collection View Not Showing Data

我的目标是将来自名为 News API 的 Web 服务的数据显示到集合视图控制器中。下面是数据模型和网络管理器。

struct News: Codable {
    var status: String?
    var totalResults: Int?
    var articles: [Article]?
    var article: Article?
    enum CodingKeys: String, CodingKey {
        case status = "status"
        case totalResults = "totalResults"
        case articles = "articles"
    }
}

// MARK: - Article
struct Article: Codable {
    var source: Source?
    var author: String?
    var title: String?
    var articleDescription: String?
    var url: String?
    var urlToImage: String?
    var publishedAt: String?
    var content: String?

    enum CodingKeys: String, CodingKey {
        case source = "source"
        case author = "author"
        case title = "title"
        case articleDescription = "description"
        case url = "url"
        case urlToImage = "urlToImage"
        case publishedAt = "publishedAt"
        case content = "content"
    }
}

// MARK: - Source
struct Source: Codable {
    var id: ID?
    var name: Name?

    enum CodingKeys: String, CodingKey {
        case id = "id"
        case name = "name"
    }
}

enum ID: String, Codable {
    case engadget = "engadget"
    case techcrunch = "techcrunch"
    case theVerge = "the-verge"
}

enum Name: String, Codable {
    case engadget = "Engadget"
    case lifehackerCOM = "Lifehacker.com"
    case techCrunch = "TechCrunch"
    case theVerge = "The Verge"
}


class NetworkManger{
    
    static let shared = NetworkManger()
    private let baseURL: String
    private var  apiKeyPathCompononent :String
     private init(){
        self.baseURL = "https://newsapi.org/v2/everything?q=NFT&sortBy=popularity&"
        self.apiKeyPathCompononent = "apiKey=d32071cd286c4f6b9c689527fc195b03"
    }
    private var jsonDecoder:JSONDecoder = {
            let decoder = JSONDecoder()
            decoder.keyDecodingStrategy = .convertFromSnakeCase
            return decoder
        }()

    
    func getArticles() {
        AF.request(self.baseURL + self.apiKeyPathCompononent, method: .get, parameters: nil, encoding: URLEncoding.default, headers: nil, interceptor: nil).response { (responseData) in
                guard let data = responseData.data else {return}
            do {
                let news = try self.jsonDecoder.decode(News.self, from: data)
                let nc = NotificationCenter.default
                nc.post(name: Notification.Name("didFinishParsing"), object: nil)
                } catch {
                    print(error)
                }
                
            }
        }    
}

它可以将来自网络服务的数据显示到控制台。问题是它无法向 NewsVC 中的集合视图显示数据。我已经完成了所有必要的步骤,例如实现集合视图数据源、使用观察者提醒 NewsVC JSON 已解析、设置集合视图布局和注册单元格,但似乎没有任何效果。下面的代码是 NewVc 和 News 网格;新闻Vc是为了展示内容。

class NewsVC: UIViewController {
    var news = [Article]()
    
    @IBOutlet weak var collectionView: UICollectionView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        configureCollection()
        NetworkManger.shared.getArticles()
    }
    
    func configureCollection(){
        collectionView.delegate = self
        collectionView.dataSource = self
        let collectionviewFlowLayout = UICollectionViewFlowLayout()
        collectionviewFlowLayout.scrollDirection  = .vertical
        collectionviewFlowLayout.itemSize = CGSize(width: 188.0, height: 264.0)
        collectionviewFlowLayout.minimumInteritemSpacing = 10.0
        collectionView.collectionViewLayout = collectionviewFlowLayout
        NotificationCenter.default.addObserver(self, selector: #selector(refreshcollectionView), name: Notification.Name("didFinishParsing"), object: nil)

    }

    @objc func refreshcollectionView(_ notification:Notification) {
        guard let news = notification.object as? Article else { return}
        print("News == \(news)")
        self.news = [news]
        print("Coount == \(self.news.count)")
        DispatchQueue.main.async {
            self.collectionView.reloadData()
        }
    }
   


extension NewsVC:UICollectionViewDataSource , UICollectionViewDelegate{

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        news.count
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionCell", for: indexPath) as! NewsGridCell
        let stories = news[indexPath.item]
        cell.setCells(stories)
        cell.backgroundColor = UIColor.red

        return cell
    }
    
class NewsGridCell: UICollectionViewCell {
    
    @IBOutlet weak var newsImage: UIImageView!
    
    @IBOutlet weak var newsDescription: UILabel!
    
    @IBOutlet weak var author: UILabel!
    
    
    func setCells(_ news:Article){
        upDateUI(newDescription:news.articleDescription, author: news.author)
    }
    
    private func upDateUI(newDescription:String? , author:String?){
        self.newsDescription.text = newDescription
        self.author.text = author
    }
    
    
}

阅读代码片段后,代码看起来应该可以工作,但实际上没有。在那种情况下,我会添加 debugPrint(#function) 来检查是否执行了以下方法:

NewsVC -> collectionView(_:numberOfItemsInSection:)
NewsVC -> collectionView(_:cellForItemAt:)
NewsGridCell -> setCells(_:)

如果那些 debugPrints 打印到控制台,那么我会去“View Hierarchy inspector”检查存在和视图的大小。

尝试代替

nc.post(name: Notification.Name("didFinishParsing"), object: nil)

发送

nc.post(name: Notification.Name("didFinishParsing"), object: news)

然后代替

guard let news = notification.object as? Article else { return}

guard let news = notification.object as? News else { return}
print("News == \(news)")
self.news = news.articles