图像无法在表格视图中显示

通过

我创建了一个带有自定义单元格的 tableView,每个单元格都有一个图像。

在模型类中,我创建了一个func mainPulatesData()使用URLSessiondataTask 方法从 url 中检索数据,并将数据转换UIImage为完成处理程序块中,然后将图像添加到UIImage.

检索数据并将它们添加到UIImage数组中的过程是在DispatchQueue.global(qos: .userInitiated).async中执行的根据打印消息,图像确实被添加到数组中。

然而,即使我在 tableView 控制器中创建了一个模型类的实例,并调用了mainPulatesData()in viewDidlLoad,图像也没有出现在表格中。

基于表视图控制器类中的其他打印消息,我发现它甚至可以添加到模型类中的数组中,但似乎不适用于 tableView 控制器中的模型类实例。

这是模型类中获取图像数据的代码:

func mainPulatesData() {
    let session = URLSession.shared
    if myURLs.count > 0{
        print("\(myURLs.count) urls")
        for url in myURLs{
            let task = session.dataTask(with: url, completionHandler: { (data,response, error)  in
                let imageData = data
                DispatchQueue.global(qos: .userInitiated).async {
                    if imageData != nil{
                        if let image = UIImage(data: imageData!){
                            self.imageList.append(image)
                            print("\(self.imageList.count) images added.")
                        }
                    }
                    else{
                        print("nil")
                    }
                }
            })
            task.resume()   
        }
    }
}

这是视图控制器中创建模型实例的代码:

override func viewDidLoad() {
    super.viewDidLoad()
    myModel.mainPulatesURLs()
    myModel.mainPulatesData()
    loadImages()
}

private func loadImages(){
    if myModel.imageList.count > 0{
        tableView.reloadData()
    }
    else{
        print("data nil")
    }
}

override func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

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

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "imageCell", for: indexPath) as! ImageTableViewCell
    if myModel.imageList.count > 0{
        let image = myModel.imageList[indexPath.row]
        cell.tableImage = image
        return cell

    }
    return cell
}
xiangxin

原因是图像或imageList尚未准备好在cellForRowAt您之后调用reloadData()

一个好的做法是在开始时使用占位符图像,并且仅在表格视图单元格可见时才加载图像,而不是一次加载所有内容。就像是:

// VC class
private var modelList = [MyModel(url: url1), MyModel(url: url2), ...]

override func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

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

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "imageCell", for: indexPath) as! ImageTableViewCell
    cell.update(model: modelList[indexPath.row])
    return cell
}

// Cell class
@IBOutlet weak var cellImageView: UIImageView!

func update(model: MyModel) {
    model.fetchImage(callback: { image in
        self.cellImageView.image = image
    })
}

// Model class
final class MyModel: NSObject {
  let url: URL
  private var _imageCache: UIImage?

  init(url: URL) {
    self.url = url
  }

  func fetchImage(callback: @escaping (UIImage?) -> Void) {
    if let img = self._imageCache {
      callback(img)
      return
    }

    let task = URLSession.shared.dataTask(with: self.url, completionHandler: { data, _, _  in
      if let imageData = data, let img = UIImage(data: imageData) {
        self._imageCache = img
        callback(img)
      } else {
        callback(nil)
      }
    })
    task.resume()
  }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章