简体   繁体   English

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

[英]How should I do to wait all the data downloaded completely and show on TableView?

I have class named ShowCarClass 我有一个名为ShowCarClass的课程

It will use TableView to show Car's name and image 它将使用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()
           }
        }

When I press Button it can call myApi() and update tableview content 当我按下Button时,它可以调用myApi()并更新tableview内容

This ViewController has 3 buttons, it will separately get different data 这个ViewController有3个按钮,它将分别获取不同的数据

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

In function cellForRowAt I use carImg's URL to download Image 在功能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
    }
}

Here's extension UIImageView 这是扩展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)
    }
}

In ShowCarClass I show startAnimating when call myAPI() 在ShowCarClass中,我在调用myAPI()时显示startAnimating

but I need to use image URL to download image 但我需要使用图片网址下载图片

This situation will make start and stop animate finish too quickly 这种情况会使启动和停止动画完成的速度过快

TableView looks like I actually get that data I need TableView看起来像我实际获得的数据

but Car's array content have URL I have to additionally process 但Car的数组内容具有我必须另外处理的URL

I hope it can download all of the image, and implement stopAnimating 我希望它可以下载所有图像,并实现stopAnimating

Step is like : user open app -> call myApi() -> startAnimating -> All of 步骤就像:用户打开应用程序->调用myApi()-> startAnimating->所有

the carName and CarImage completely -> stopAnimating -> load into TableView carName和CarImage完全-> stopAnimating->加载到TableView中

-> user can see all the car informations (can't swipe tableview until data finished) ->用户可以查看所有汽车信息(在数据完成之前无法滑动表格视图)

I'm really new, not good at questioning if need more info just ask for me, Thanks. 我真的很新,不擅长询问是否需要更多信息,谢谢。

You can use DispatchGroup 您可以使用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()
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM