Swift - ReloadData 未更新

Swift - ReloadData not update

我正在尝试用 Json 结构中的数据填充 Swift 中的 CollectionView,但我无法重新加载数组并解析到 collectionView 我正在声明一个 Array(V_textoturismo) 并将 JSON 的内容解析到它,但似乎无法或者当它通过时我无法重新加载集合视图。 如果我用 static Array(texto) 做它,我做不到没有问题 谢谢 4 一切 我附上我的代码:

import UIKit

struct category: Codable {
           let textoturismo: String
           let imagenturismo: String
           let destinoturismo: String
}
struct Entry_category: Codable {
           let categories: [String: category]
}

class CollectionViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
    
    @IBOutlet weak var collectionView: UICollectionView!
    @IBOutlet var menuButton:UIBarButtonItem!
    
    var v_textoturismo:[String] = []
    var v_imagenturismo:[String] = []
    var v_destinoturismo:[String] = []
    
    let imagen = ["Perdidos", "Friends", "Breaking Bad", "Dexter"]
    let texto = [NSLocalizedString("Hotels", comment: ""),
                        NSLocalizedString("Restaurants", comment: ""),
                        NSLocalizedString("Bars&Pubs", comment: ""),
                        NSLocalizedString("Discoteques", comment: "")]

    override func viewDidLoad() {
        super.viewDidLoad()
        //collectionView?.dataSource = self;
        //collectionView?.delegate = self;
        
        if self.revealViewController() != nil {
            menuButton.target = self.revealViewController()
            menuButton.action = #selector(SWRevealViewController.revealToggle(_:))
            self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
        }
        if let layout = collectionView?.collectionViewLayout as? UICollectionViewFlowLayout{
            //layout.minimumLineSpacing = 10
            //layout.minimumInteritemSpacing = 10
            //layout.sectionInset = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 0)
            //let size = CGSize(width:(collectionView!.bounds.width)/2, height: 150)
            let size = CGSize(width:(collectionView!.frame.size.width)/2, height: 150)
            layout.itemSize = size
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        
    }
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return v_textoturismo.count
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let identifier = "Item"
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: identifier, for: indexPath) as! SeriesCollectionViewCell
        //cell.itemLabel.text = texto[indexPath.row]
        cell.itemLabel.text = v_textoturismo[indexPath.row]
        cell.itemImage.image = UIImage.init(imageLiteralResourceName: imagen[indexPath.row])
        return cell
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        let item = sender as? UICollectionViewCell
        let indexPath = collectionView.indexPath(for: item!)
        let detailVC = segue.destination as! DetailViewController
        detailVC.detailName = imagen[(indexPath?.row)!]
    }
    
    func parseCategories(){
        //Leo JSON categorias
               
               NSLog("entro")
               if let url2 = URL(string: "http://s369243288.mialojamiento.es/WS_CB_Addicts/categorias_turismo/json_data.php") {
                  URLSession.shared.dataTask(with: url2) { data, response, error in
                     if let data = data {
                     let jsonDecoder = JSONDecoder()
                     do {
                     let parsedJSON = try jsonDecoder.decode(Entry_category.self, from: data)
                     for category in parsedJSON.categories {
                       self.v_textoturismo.append(category.value.textoturismo)
                       print(category.value.textoturismo)
                       self.v_imagenturismo.append(category.value.imagenturismo)
                       self.v_destinoturismo.append(category.value.destinoturismo)
                       print(category.value.destinoturismo)
                     //print(image.value.destino)
                                 }
                             } catch {
                     print(error)
                             }
                            }
                        }.resume()
               }
               //End Leo JSON categorias
    }
    
    override func viewWillAppear(_ animated: Bool) {
          //super.viewWillAppear(animated)
          parseCategories()
          //self.collectionView.reloadData()
        DispatchQueue.main.async {
            self.collectionView.reloadData()
        }
        print(v_textoturismo)
      }
}

您的 collection 视图数据源行被注释掉了,所以我假设您是在 Interface Builder / Storyboards 中设置它?

        //collectionView?.dataSource = self;
        //collectionView?.delegate = self;

如果未设置这些,您的 collection 视图将始终为空。

旁注:此处不需要分号

接下来,查看您的 viewWillAppear 方法,这里有多个问题。首先,总是总是总是调用 super 除非框架明确告诉你不要这样做。在 iOS 的未来版本中,此处可能存在您可能会错过的隐藏行为。

事实上,docs state:

If you override this method, you must call super at some point in your implementation.

接下来,您可能会考虑只在 viewDidLoad 中调用 parseCategories 而不是 viewWillAppear。您可能不希望他们每次到达此屏幕时都调用它,例如,如果他们切换标签页。

您的 DispatchQueue.main.async 电话在这里是不必要的。此方法始终在主队列上调用。

这里调用reloadData也不对,你想在有新数据加载的时候调用,而此时你刚刚调用了parseCategories发出了网络请求,所以你得等它先回来。

在您的 parseCategories 方法中,您没有处理网络请求返回 Error 或 non-successful HTTP 状态代码的情况。

最后,在解析数据后的成功块中,您将类别添加到数组中,但您从未告诉 collection 视图在此处重新加载。您需要:

DispatchQueue.main.async { 
    self.collectionView.reloadData()
}

将数据添加到 v_textoturismo 数组后。