显示进度条,直到 UITableView 加载所有 Cell

     2023-02-27     202

关键词:

【中文标题】显示进度条,直到 UITableView 加载所有 Cell【英文标题】:Show progressBar until UITableView load all 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)")
        
    

    


【问题讨论】:

【参考方案1】:

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

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

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

【讨论】:

感谢您的回答,但您能用一些示例代码更好地解释一下吗?

jQuery进度条加载直到页面重定向

...个隐藏的附属链接,在1秒后使用jQuery单击该链接。我想显示jQuery加载栏进度,直到页面重定向到附属链接。我该怎么做?【问题讨论】:你有没有写代 查看详情

进度条,直到从服务器加载数据

】进度条,直到从服务器加载数据【英文标题】:Progressbaruntiltheloadofdatafromserver【发布时间】:2016-12-1015:16:28【问题描述】:publicclassRecyclerviewextendsAppCompatActivityprivateRecyclerViewmRecyclerView;CustomAdaptercu;ArrayList<Employee>arr,ar 查看详情

如何在加载时加载自定义进度条

...:09:53【问题描述】:我有一个要求,我需要在初始屏幕上显示进度条/活动指示器,直到我在iOS7中完成数据下载。提前致谢【问题讨论】:【参考方案1】:如果您想显示自定义(或本机)活动指示器,那么您不需要自定义启动图... 查看详情

如何在使用 GoogleMap 的活动完全加载之前显示进度条

】如何在使用GoogleMap的活动完全加载之前显示进度条【英文标题】:HowtodisplayprogressbarbeforeactivitywithGoogleMapisfullyloaded【发布时间】:2017-10-2401:32:28【问题描述】:我的一项活动中有一个Mapview。每当单击按钮并打开包含Mapview的Acti... 查看详情

如何只实现一个圆形进度条,直到图像被滑动加载

】如何只实现一个圆形进度条,直到图像被滑动加载【英文标题】:Howtoimplementonlyonecircularprogressbaruntilimagesareloadedwithglide【发布时间】:2021-08-2406:49:15【问题描述】:您好,我只想实现一个圆形进度动画,直到从滑行加载图像,... 查看详情

uitableview中的ios进度条

】uitableview中的ios进度条【英文标题】:iosprogressbarinuitableview【发布时间】:2013-11-2113:46:53【问题描述】:我是ios新手,如何在uitableview中更新进度条。通常我有一个按钮,当我单击特定单元格中的按钮时,我只需要在该单元格... 查看详情

从数据库中检索数据时如何显示加载动画或进度条?

】从数据库中检索数据时如何显示加载动画或进度条?【英文标题】:Howtoshowloadinganimationsorprogressbarswhenretrievedatafromdatabase?【发布时间】:2015-04-3017:30:41【问题描述】:每次访问此页面时,我都会从数据库中检索大约15,000行。该... 查看详情

UITableView 拖动阻止所有其他动画

】UITableView拖动阻止所有其他动画【英文标题】:UITableViewdragblocksallotheranimations【发布时间】:2014-05-1912:32:51【问题描述】:我有一个使用AVPlayer流式传输视频的应用程序。我在同一个视图上还有一个进度条和一个tableView。我遇... 查看详情

加载数据并填充到recyclerview时如何显示进度条?

】加载数据并填充到recyclerview时如何显示进度条?【英文标题】:Howtodisplayprogressbarwhileloaddataandfillintorecyclerview?【发布时间】:2018-02-1217:22:33【问题描述】:我想在加载数据和加载完成时在活动中显示进度条,隐藏进度条(GONE... 查看详情

如何在加载数据之前在颤动中显示进度条

】如何在加载数据之前在颤动中显示进度条【英文标题】:Howtoshowprogressbarinflutterbeforeloadingdata【发布时间】:2022-01-0215:44:19【问题描述】:我有一个请求功能,我想在加载数据之前显示一个进度条,但我不知道该怎么做。谁能... 查看详情

进度条加载后显示页面

思路:加入很多图片,以延迟加载时间,实现加载完后显示图片。定义一个外层DIV,覆盖住图片,在内层DIV中引入加载时显示的图片,让内层DIV居中在页面上,利用setInterval定时器设置3秒后将外层DIV隐藏,从而显示图片,达到加... 查看详情

网页加载进度条

...网页加载时,有时内容过多,一直加载等待,而此时网页显示白色不显示任何的东西,给用户的体验相当不好,所以,一般会在网页加载成功前,会以进度条的形式,给用户进行展示。让用户可以看到动画,知道网页正在加载中... 查看详情

网站顶部显示预加载进度条preload.js

网站加载的速度快的话,不会显示进度条加载时候的样式。 支持性主流浏览器都支持,ie浏览器需要9以上9也支持。使用方法<scriptsrc="http://code.jquery.com/jquery-1.7.1.min.js"></script><scriptsrc="js/preload.js"></script><sc... 查看详情

禁用按钮,直到 UITableView 加载来自 Parse.com 的数据

】禁用按钮,直到UITableView加载来自Parse.com的数据【英文标题】:DisablingbuttonuntilUITableViewisloadedwithdatafromParse.com【发布时间】:2015-05-2817:59:28【问题描述】:我正在使用parse.com开发一个小应用程序。该应用程序将从Parse.com加载数... 查看详情

当片段视图加载是异步任务的一部分时,如何在片段加载之前显示进度条?

...段视图加载是异步任务的一部分时,如何在片段加载之前显示进度条?【英文标题】:Howtoshowprogressbarbeforefragmentloadingwhenfragmentviewloadingispartofasynctask?【发布时间】:2018-04-1621:50:48【问题描述】:我有一个片段来显示日历月视图... 查看详情

进度条(视频预加载器)

...er)【发布时间】:2011-03-0102:54:48【问题描述】:我有一个显示视频的火花组件VideoDisplay。我想向它添加一个ProgressBar,它将显示视频的加载进度以及视频加载时ProgressBar消失。我该怎么做?【问题讨论】:【参考方案1】:使用s:Vi... 查看详情

动画进度条以显示网页的进度

】动画进度条以显示网页的进度【英文标题】:animatingprogressbartoshowtheprogressofwebpage【发布时间】:2013-08-1202:20:56【问题描述】:我的页面顶部有一个进度条,我希望该条显示网页加载的进度。当整个页面加载时,我希望栏显示10... 查看详情

UItableView 在滚动时加载数据 10 10 条记录

】UItableView在滚动时加载数据1010条记录【英文标题】:UItableViewloaddata1010recordsonscroll【发布时间】:2014-04-0407:29:24【问题描述】:我正在从网络服务获取数据,我必须在UITableView中显示它。但这里的条件是我最初只能显示10条记录... 查看详情