ios - 如何等待所有数据下载完成并显示在TableView上?

标签 ios swift

我有一个名为 ShowCarClass 的类

它将使用 TableView 显示汽车的名称和图像

class ShowCarClass:UIViewController {

@IBOutlet weak var tableView: UITableView!
var car = [Car]()

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

    func myAPI() {
         startAnimating()
         let json = CarType.Request
         api.getAPIResponse(apiURL:.Car ,jsonType: json) {(isSuccess, result) in

         switch isSuccess {

         case true: 
         let successResult = result as! CarType.Response
         //car array result like this
                 [Car(carName:"BMW",carImg:"https://00.00.00/static/image/BMW.png"),Car(carName:"Audi",carImg:"https://00.00.00/static/image/Audi.png")]
                 self.tableView.delegate = self
                 self.tableView.dataSource = self
                 self.tableView.reloadData()

         case false:
         self.APIErrorStatus(result)
                }
          stopAnimating()
           }
        }

当我按下 Button 时,它可以调用 myApi() 并更新 tableview 内容

这个ViewController有3个按钮,分别获取不同的数据

@IBAction func btnPress(_ sender: UIButton) {
         callAPI()
}

在函数 cellForRowAt 中,我使用 carImg 的 URL 下载图像

extension ShowCarClass:UITableViewDelegate, UITableViewDataSource{
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return car.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CarCell
        cell.carNameLabel.text = car[indexPath.row].carName
        cell.carImageView.downloaded(from:car[indexPath.row].carImg, contentMode: .scaleToFill)
        return cell
    }
}

这是 UIImageView 的扩展

extension UIImageView {
    func downloaded(from url: URL, contentMode mode: UIView.ContentMode = .scaleAspectFit) {
        contentMode = mode
        URLSession.shared.dataTask(with: url) { data, response, error in

        guard   let httpURLResponse = response as? HTTPURLResponse, httpURLResponse.statusCode == 200,
                let mimeType = response?.mimeType, mimeType.hasPrefix("image"),
                let data = data, error == nil,
                let image = UIImage(data: data) else {
                    return
            }

            DispatchQueue.main.async() {
                self.image = image
            }

            }
            .resume()
    }

    func downloaded(from link: String, contentMode mode: UIView.ContentMode = .scaleAspectFit) {
        guard let url = URL(string: link) else { return }
        downloaded(from: url, contentMode: mode)
    }
}

在 ShowCarClass 中,我在调用 myAPI() 时显示 startAnimating

但我需要使用图片网址来下载图片

这种情况会使启动和停止动画完成得太快

TableView 看起来我确实得到了我需要的数据

但是 Car 的数组内容有 URL 我必须另外处理

希望它能下载所有的图片,并实现stopAnimating

步骤如下:用户打开应用程序 -> 调用 myApi() -> startAnimating -> 所有

carName 和 CarImage 完全 -> 停止动画 -> 加载到 TableView

-> 用户可以看到所有的汽车信息(在数据完成之前不能滑动tableview)

我真的很新,不擅长提问如果需要更多信息就问我,谢谢。

最佳答案

你可以使用 DispatchGroup

let dispatchGroup = DispatchGroup()

let imageCount = 10

for _ in 1...imageCount{
   dispatchGroup.enter()
   ImageDownloader.download(image: "url") { result in
      dispatchGroup.leave()
   }
}

dispatchGroup.notify(queue: .main) 
    tableView.reloadData()
}

关于ios - 如何等待所有数据下载完成并显示在TableView上?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56650366/

相关文章:

Swift 便捷下标

cocoa - NSView 的 subview 如何动态定位?

ios - 如何在 Alamofire 中使用 PUT 请求

ios - Firebase 数据库

iphone - 快速枚举在objective-c中没有给出正确的对象类型?

ios - 在 iOS 中发送通知有哪些可能性

ios - 通过索引路径更改 CLLocationCooperative2DMake 使用数组

ios - 如何从 firebase 获取数据以供我的应用程序中的每个类使用 - swift ios 开发

ios - 具有多个 subview 的 UIScrollView

iphone - UILabel需要setNumberOfLines以适合我的文字大小