【问题标题】:Show progressBar until UITableView load all Cell显示进度条,直到 UITableView 加载所有 Cell
【发布时间】:2021-11-06 05:05:32
【问题描述】:

我正在使用 Swift 5 构建一个应用程序。 我用 UITableView 创建了一个视图。我需要显示进度条,直到所有 Cell 都加载完毕。问题是,对于每个单元格,我都从 url 加载图像,并且我需要显示进度条,直到所有图像都加载完毕。这是代码:

import UIKit
import SwiftyJSON

class MenuSelectedVC: UIViewController, UITableViewDataSource, UITableViewDelegate, UpdateCartProtocol {

    @IBOutlet weak var lblChiusura: UILabel!
    @IBOutlet weak var lblStoreAddress: UILabel!
    @IBOutlet weak var lblStoreName: UILabel!
    
    @IBOutlet weak var tableViewData: UITableView!
    @IBOutlet weak var viewBtnRating: UIView!
    @IBOutlet weak var viewProductCart: UIView!
    var store:StoreResponseModel!
    var category:ProductCategory!
    var products:[Product] = []
    var quantity:Int!
    var price:Float!
    var cart:ResponseCartModel!
    @IBOutlet weak var lblNumProduct: UILabel!
    @IBOutlet weak var lblTotalChart: UILabel!
    //MARK:- ViewDidLoad
    override func viewDidLoad() {
        super.viewDidLoad()
        self.showProgressBar()
        tableViewData.delegate = self
        tableViewData.dataSource = self
        self.settingUi()
        getCart()
        getProductByCategory()
        self.hideProgressBar()
    }
    
    func getProductByCategory(){
        self.showProgressBar()
        var paramDict : [String:AnyObject] = [:]
        paramDict["store_id"]  = store.id as AnyObject
        paramDict["category_id"]  = category.id as AnyObject
        paramDict["activate"]  = "1" as AnyObject
        CommunicationManeger.callPostServiceReturnJson(apiUrl: RouterProd.get_product_by_store.url(), parameters: paramDict,  parentViewController: self, successBlock: { (responseData, message) in

            DispatchQueue.main.async { [self] in
                do {
                    let products = try JSONDecoder().decode(ResponseProductModel.self, from: responseData as! Data)
                    if(products.status == "1") {
                        self.products = products.result
                        self.tableViewData.reloadData()
                    } else {
                        self.products = []
                        //self.table_List.reloadData()
                        Utility.noDataFound(products.message, tableViewOt: self.tableViewData, parentViewController: self)
                    }
                }catch{
                   print("errore durante la decodifica dei dati: \(error)")
                   Utility.noDataFound("Errore", tableViewOt: self.tableViewData, parentViewController: self)
               }
                
                self.hideProgressBar()
            }
        }, failureBlock: { (error : Error) in
            Utility.showAlertMessage(withTitle: EMPTY_STRING, message: (error.localizedDescription), delegate: nil,parentViewController: self)
            self.hideProgressBar()
        })
    }
    
    func updateCartFromProtocol(prodottoAggiornato: ResultCartModel) {
        self.price = nil
        self.quantity = nil
        //devo aggiornare il prodotto appena modificato
        //verifico questo prodotto a che numero riga era
        let position:Int = try! searchProductPosition(nomeProdotto: prodottoAggiornato.productDetails.productName) as! Int
        if(position != nil){
            //dal array recupero l oggetto inq uesta posizione
            self.cart.result.indices.filter { self.cart.result[$0].productDetails.productName == prodottoAggiornato.productDetails.productName}
                .forEach { self.cart.result[$0].quantity = prodottoAggiornato.quantity }
            let indexPosition = IndexPath(row: position, section: 0)
            tableViewData.reloadRows(at: [indexPosition], with: .none)
        }
        getCart()
    }
    
    func getCart(){
        self.showProgressBar()
        var paramDict : [String:AnyObject] = [:]
        paramDict["user_id"]  = UserDefaults.standard.value(forKey: USERID) as AnyObject?
        CommunicationManeger.callPostServiceReturnJson(apiUrl: RouterProd.get_cart.url(), parameters: paramDict,  parentViewController: self, successBlock: { (responseData, message) in

            DispatchQueue.main.async { [self] in
                do {
                    self.cart = try JSONDecoder().decode(ResponseCartModel.self, from: responseData as! Data)
                    if(cart.status == "1") {
                        for product in cart.result {
                            if(product.type == TYPE_PRODUCT){
                                let detail = product.productDetails
                                self.updateQuantity(quantita: Int(product.quantity)!)
                                //se ci sono aggiunte il prezzo va
                                //preso dal prodotto generale altrimenti
                                //dal suo dettaglio
                                if(product.ingredientPrice.isEmpty){
                                    self.updateTotalPrice(quantita: Int(product.quantity)!, prezzo: Float(detail.price)!)
                                }else{
                                    self.updateTotalPrice(quantita: Int(product.quantity)!, prezzo: Float(product.ingredientPrice)!)
                                }
                                
                            }
                        }
                        
                    } else {
                        
                    }
                }catch{
                   print("errore durante la decodifica dei dati: \(error)")
                   
               }
                
                self.hideProgressBar()
            }
        }, failureBlock: { (error : Error) in
            Utility.showAlertMessage(withTitle: EMPTY_STRING, message: (error.localizedDescription), delegate: nil,parentViewController: self)
            self.hideProgressBar()
        })
    }
    
    func settingUi(){
        self.viewBtnRating.setCornerRadius(cornerRadius: 14, borderColor: nil, borderWidth: nil)
        viewProductCart.setCornerRadius(cornerRadius: 25, borderColor: nil, borderWidth: nil)
        self.lblStoreName.text = self.store.firstName
        self.lblStoreAddress.text = self.store.address
    }
    
    @IBAction func btnBack(_ sender: Any) {
        self.navigationController?.popViewController(animated: true)
    }

    @IBAction func btnViewCart(_ sender: Any) {
        let vc = self.storyboard?.instantiateViewController(withIdentifier: "AddToCartVC") as! AddToCartVC
        self.navigationController?.pushViewController(vc, animated: true)
    }
    
    //MARK:- TableView Methods
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
        
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.products.count
        
    }
    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
            if let lastVisibleIndexPath = tableViewData.indexPathsForVisibleRows?.last {
                    if indexPath == lastVisibleIndexPath {
                        print("finisco di scrivere le righe")
                    }
            }
        }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableViewData.dequeueReusableCell(withIdentifier: "MenuSelectedCell") as! MenuSelectedCell
        let obj = self.products[indexPath.row]
        let image = obj.image[0].image
        let url = URL(string: image)!
        if let data = try? Data(contentsOf: url) {
            cell.imgFood.image = UIImage(data: data)
        }
        cell.lblNameProduct.text = obj.productName
        cell.lblDescriptionProduct.text = obj.resultDescription
        cell.lblPriceProduct.text = obj.price + " €"
        //devo verificare se i prodotti della categoria sono stati già selezionati oppure no.
        do{
            let cartObj = try? searchProduct(nomeProdotto: obj.productName)
            if(cartObj != nil){
                cell.lblQuantity.text = cartObj?.quantity
                cell.quantita = Int(cartObj!.quantity)
            }else{
                cell.lblQuantity.text = "0"
                cell.quantita = 0
            }
        }catch{
            
        }
        cell.buttonAdd.tag = indexPath.row
        cell.buttonAdd.addTarget(self, action: #selector(addQuantity(button:)), for: .touchUpInside)
        cell.buttonMinus.addTarget(self, action: #selector(removeQuantity(button:)), for: .touchUpInside)
        return cell
    }
    
    func searchProduct(nomeProdotto: String) -> ResultCartModel?{
        if(self.cart != nil){
            if let i = self.cart.result.firstIndex(where: { $0.productDetails.productName == nomeProdotto }) {
                return self.cart.result[i]
            }
        }
        return nil
    }
    
    func searchProductPosition(nomeProdotto: String) -> Int?{
        if(self.cart != nil){
            if let i = self.cart.result.firstIndex(where: { $0.productDetails.productName == nomeProdotto }) {
                return i
            }
        }
        return nil
    }
    
    func updateQuantity(quantita: Int){
        do{
            if(quantity == nil){
                quantity = quantita
            }else{
                self.quantity += quantita
            }
            lblNumProduct.text = String(self.quantity) + " Prodotti"
        }catch{
            print("caught: \(error)")
        }
    }
    
    func updateTotalPrice(quantita: Int, prezzo: Float){
        do{
            if(self.price == nil){
                self.price = Float(quantita) * prezzo
            }else{
                self.price += Float(quantita) * prezzo
            }
            lblTotalChart.text = "€ " +
                Utility.twoDecimals(number: self.price!)
        }catch{
            print("caught: \(error)")
        }
    }

    

}

【问题讨论】:

    标签: swift uitableview


    【解决方案1】:

    系统不会一次加载UITableView 中的所有单元格。相反,它只加载可见的单元格,并显示这些单元格。当用户开始滚动时,它可能会删除一些不再可见的单元格,并为新可见的内容添加其他单元格。

    您不希望在创建单元格时尝试为目录项加载图形。

    而是将数据加载移动到您的模型类中并在那里加载图像。您可以在表格中放置一个占位符单元格以显示目录图像正在后台加载,然后在加载完成后填充表格。

    【讨论】:

    • 感谢您的回答,但您能用一些示例代码更好地解释一下吗?
    猜你喜欢
    • 1970-01-01
    • 2012-11-09
    • 2013-04-27
    • 1970-01-01
    • 2011-01-30
    • 1970-01-01
    • 2017-07-20
    • 2011-06-19
    • 1970-01-01
    相关资源
    最近更新 更多