【问题标题】:Collection View Not Showing Data集合视图不显示数据
【发布时间】:2021-06-29 18:32:06
【问题描述】:

我的目标是将来自名为 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)
                }
                
            }
        }    
}

它可以将来自 Web 服务的数据显示到控制台。问题是它不能在 NewsVC 的集合视图中显示数据。我已经完成了所有必要的步骤,例如实现集合视图数据源、使用观察者提醒 NewsVC JSON 已解析、设置集合视图布局和注册单元格,但似乎没有任何效果。下面的代码是NewVc 和News 网格; 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
    }
    
    
}

【问题讨论】:

    标签: ios swift uicollectionview uikit


    【解决方案1】:

    尝试代替

    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
    

    【讨论】:

    • 非常感谢它有效。你能解释一下你的方法吗?
    • 如您所见,您没有将新闻数据发送到 CollectionView 数据源。你发送了 nil 。然后你解析文章而不是新闻。如果您发送新闻,那么您会收到新闻。但是您发送了新闻并期待文章。类似的东西。我想你打错了。
    • 由于 Articles 类包含 JSON 的属性,我认为它会起作用。在解析 JSON 并在任何视图控制器中显示它时,我应该使用数据模型 News 或 Articles 中的哪个类?
    • 这取决于要求。在您的情况下,您需要文章来显示它们,但服务器会返回新闻。只有一条新闻(在你的情况下)。您应该解析新闻,然后使用文章作为 collectionview 的模型。顺便说一句,我猜“var 文章:文章?”在新闻结构中是多余的。我想服务器会返回一系列新闻。找出来。如果是这样,您应该使用分段集合视图。我想是的。
    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 2014-10-06
      • 1970-01-01
      • 2021-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-02
      • 1970-01-01
      相关资源
      最近更新 更多