重新加载 ViewController 中的 tableview 让我在索引路径的 cellforRow 中出现“致命错误:索引超出范围”

Posted

技术标签:

【中文标题】重新加载 ViewController 中的 tableview 让我在索引路径的 cellforRow 中出现“致命错误:索引超出范围”【英文标题】:Reloading the tableview inside a ViewController getting me ' Fatal error: index out of range' , in cellforRow at index path 【发布时间】:2019-04-23 06:45:50 【问题描述】:

当我打开视图时,它会快速打开并且不显示任何错误,但是当我重新打开它时,它会给我“致命错误”。这是 ViewController 中的一个表格视图,它正在获取数据,但是当我重新打开视图时它会出错。

当我再次调用 tableview 时,tableview 嵌入在视图控制器中,它在 ViewController 内给出了超出范围的致命错误索引。这需要解决我认为问题在于我在返回数组的部分中的行数。

import UIKit
import Alamofire
import Foundation

protocol Quantitypass 
    func qtypass(qty: String, product_id: String)


public struct QtyCart 
    var qty : String!

    public init(qty: String) 
        self.qty = qty
    


public struct FavouriteCart 
    var p_name : String!
    var p_price : String!
    var p_id : String!
    var qty: String!

    public init(p_name: String ,  p_price: String , p_id : String, qty: String) 
        self.p_name = p_name
        self.p_price = p_price
        self.p_id = p_id
        self.qty = qty
    


public struct favSection 
    var favitems: [FavouriteCart]

    public init(favitems: [FavouriteCart]  ) 
        self.favitems = favitems
    


public struct MyVariables 
    static var product2 = "p_id"


public var cartData: [favSection] = []

class newCartViewController: UIViewController 
    @IBAction func btnSubmit(_ sender: UIButton) 
        self.loadnextVC()
    

    func loadnextVC() 
        let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
        let newViewController = storyBoard.instantiateViewController(withIdentifier: "finalVC")
        self.present(newViewController, animated: true, completion: nil)
    

    @IBOutlet weak var lblPreorder: UILabel!
    @IBOutlet weak var lblOrdermethod: UILabel!
    @IBOutlet weak var lblTotalAmount: UILabel!

    // public var itemsData: [Item] = []
    var lblOrder = String()
    // let productPrice = UserDefaults.standard.object(forKey: "p_price")
    let cartid = UserDefaults.standard.object(forKey: "deviceUUID") as? String
    let getApi = RestaurantAPI.self

    var qtyData: [QtyCart] = []
    //    var currentSection = 0
    //    var currentRow = 1
    // var calculation1 = cartTableViewCell()

    @IBOutlet weak var tableView: UITableView!

    @IBAction func dismiss(_ sender: Any) 
        self.dismiss(animated: true, completion: nil)
        self.lblTotalAmount.text = ""
    

    //public var cartData: [FavouriteCart] = []
    var refreshControl = UIRefreshControl()
    var buttonClicked = statusViewController.self
    var btn2 = UserDefaults.standard.object(forKey:"button1") as? Bool
    var btn3: Bool =  true
    weak var delegate: DetailsDelegate?

    override func viewDidLoad() 
        super.viewDidLoad()
        self.getTotal1()
        print("@------/\(cartData.count)")

        //self.updateLabel(withString: lblTotalAmount.text)
        if btn2 != btn3 
            lblPreorder.isHidden = true
            lblOrdermethod.isHidden = false
            print("BUTTONCLICKED")
            UserDefaults.standard.removeObject(forKey: "button1")
         else if btn2 == btn3 
            lblPreorder.isHidden = false
            lblOrdermethod.isHidden = true
            print("BUTTON-NOT-CLICKED")
            UserDefaults.standard.removeObject(forKey: "button1")
        

        //        if #available(ios 10.0, *) 
        //        tableView.refreshControl = refreshControl
        //         else 
        //        tableView.addSubview(refreshControl)
        //
        //        
        //        self.refreshControl.attributedTitle = NSAttributedString(string: "Pull to refresh")
        //        self.refreshControl.addTarget(self, action: #selector(newCartViewController.refreshData), for: UIControlEvents.valueChanged)
        //
    

    override func viewWillAppear(_ animated: Bool) 
        super.viewWillAppear(animated)
        self.view.addSubview(self.tableView)
        self.tableView.dataSource = self
        self.tableView.delegate = self

        self.getTotal1()
        self.getFav()
        self.tableView.reloadData()

        // self.updateTableview()
        // self.getTotal1()
    

    func getFav() 
        getFav(completionHandler:  success in
            if success 
                DispatchQueue.main.async
                    self.tableView.reloadData()
                
            
        )
    

    //TOTAL API CALL:
    func getTotal1() 
        if cartid != nil 
            let request = getApi.getamountcartGetWithRequestBuilder(restId: "17", cartId: cartid!)
            Alamofire.request(request.URLString, method: .get , parameters: nil, encoding: JSONEncoding.default)
                .responseJSON  response in
                    print("123321#######/\(response)")
                    let res = response
                    print("101res/\(res)")

                    if let value = response.value as? [String: AnyObject] 
                        if let success = value["error"] as? Bool 
                            if success == false 
                                // var  grandtotal: Any?  = value["total"]
                                if let grandtotal = value["total"] as? Double 
                                    self.lblTotalAmount.text = String(grandtotal)
                                    print("!@/\(String(grandtotal))")
                                    var g = String(grandtotal)
                                    UserDefaults.standard.set(g, forKey: "g")
                                
                                // self.tableView.reloadData()
                            
                        
                    
            
        
    

    //
    // Mark: getting all cart items:-->
    func getFav(completionHandler: @escaping (Bool) -> Void)
        if cartid != nil 
            let request = getApi.displaycartGetWithRequestBuilder(restId: "17", cartId:cartid!)
            Alamofire.request(request.URLString, method: .get , parameters: nil, encoding: JSONEncoding.default)
                .responseJSON  response in
                    print("123321/\(response)")
                    let res = response
                    print("101res/\(res)")

                    //                let total =  cartData
                    //                print("cartd1/\(total)")

                    if let value = response.value as? [String: AnyObject] 
                        if let success = value["error"] as? Bool 
                            if success == false 
                                print("2222/\(response)")
                                if let response = value["cartdata"]  as? [String: AnyObject] 
                                    let cart = response["simple"] as! [[String: AnyObject]]
                                    //                let total = value["total"] as! [String: Any]
                                    //                print("1231231231234/\(total)")
                                    //let userdata: [Favourites] = []
                                    //
                                    var cartitems: [FavouriteCart] = []
                                    for (_ , value) in cart.enumerated() 

                                        let obj = value
                                        let p_name = obj["p_name"] as! String
                                        let p_price = obj["p_price"] as! String
                                        let p_id = obj["p_id"] as! String
                                        let qty = obj["qty"] as! String

                                        //  UserDefaults.standard.set(qty, forKey: "qty")

                                        let item = FavouriteCart(p_name: p_name, p_price: p_price, p_id: p_id, qty: qty)

                                        cartitems.append(item)

                                        DispatchQueue.main.async
                                            print("RELOADED-----ON-----API")
                                            cartData.append(favSection(favitems: cartitems))
                                            self.tableView.reloadData()
                                        
                                    
                                
                                print("COMPLETION-------------HANDLER")
                                completionHandler(true)
                            
                        
                        else
                        
                            let myAlert = UIAlertController(title:"Alert",message:value["error_msg"] as? String,preferredStyle:UIAlertControllerStyle.alert)
                            let okAction = UIAlertAction(title:"OK",style:UIAlertActionStyle.default , handler: nil)
                            myAlert.addAction(okAction)
                        
                    
            
        
    

    // Mark:--> Delete items from cart.
    // func delFav(p_id: String ,completionHandler: @escaping (Bool) -> Void) 
    func delFav(p_id: String, completionHandler: @escaping (Bool) -> Void)
        //var product1 = UserDefaults.standard.object(forKey: "p_id")
        //print("this is my \(product1)")
        let request = getApi.deleteproductcartGetWithRequestBuilder(restId: "17", cartId: cartid!, productId: p_id , freeDish: "none", type: "simple")
        Alamofire.request(request.URLString, method: .delete , parameters: nil, encoding: JSONEncoding.default)
            .responseJSON  response in
                print("del favvvvvvvvv\(response)")
                print("<<DELETED ------------ ITEM>>")
                //print(response)
                if let value = response.value as? [String: AnyObject] 
                    if let success = value["error"] as? Bool 
                        if success == false 
                            let response = value["cartdata"] as? [String]
                            print("10001 - > /\(response)")

                            //self.tableView.reloadData()
                         else
                        
                            print("error message")
                        
                    
                
                // completionHandler(true)
        
    


    func delterow(p_id: String) 
        self.delFav(p_id: p_id, completionHandler: sucess in
            if sucess 
                self.tableView.reloadData()
                print("DELETED_ITEM")
            
        )
    

    func updateTotal(withString string: String?) 
        lblTotalAmount.text = string
    



extension newCartViewController: UITableViewDelegate , UITableViewDataSource  
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat 
        return 90;
    

    //     func numberOfSections(in tableView: UITableView) -> Int 
    //        return cartData.count
    //    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        // return sectionsData[section].items.count
        // return cartData[section].favitems.count
        //  return cartData[section]..count
        return cartData.count
    

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let cell = tableView.dequeueReusableCell(withIdentifier: "cartTablecell", for: indexPath) as! cartTableViewCell
        let item: FavouriteCart = cartData[indexPath.section].favitems[indexPath.row]

        cell.btnsub1.tag = indexPath.row
        cell.btnadd1.tag = indexPath.row

        cell.lblItemName.text = item.p_name
        cell.productPrice.text = item.p_price
        cell.lblprice.text = item.p_price
        cell.lblQuantity.text = item.qty

        return cell
    

    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool
        return true
    

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) 
        if (editingStyle ==  .delete) 
            if cartData.isEmpty
                print("EmptyCart")
            else 
                print("0-0/\(cartData.count)")
                // let item: Item = sectionsData[indexPath.section].items[indexPath.row]
                let item: FavouriteCart = cartData[indexPath.section].favitems[indexPath.row]

                self.tableView.beginUpdates()
                cartData.remove(at: indexPath.row)
                self.tableView.deleteRows(at: [indexPath], with: .fade)
                self.delterow(p_id: item.p_id)
                self.getTotal1()
                self.tableView.endUpdates()
            
        
    

【问题讨论】:

【参考方案1】:

它给出了错误,因为这些行保存在本地但我再次调用数据更改是:

关闭视图时必须删除整个购物车

@IBAction func dismiss(_ sender: Any) 
      self.dismiss(animated: true, completion: nil)
      self.lblTotalAmount.text = ""
      cartData.removeAll()
 

【讨论】:

【参考方案2】:

我认为 self.tableView.dataSource = self & self.tableView.delegate = self 应该在 viewDidLoad 方法中。将其添加到 viewDidLoad 可能会起作用。

【讨论】:

以上是关于重新加载 ViewController 中的 tableview 让我在索引路径的 cellforRow 中出现“致命错误:索引超出范围”的主要内容,如果未能解决你的问题,请参考以下文章

重新加载 ViewController 中的 tableview 让我在索引路径的 cellforRow 中出现“致命错误:索引超出范围”

如何在 ipad 的另一个 ViewController 中重新加载 rootViewController

从另一个 ViewController 重新加载 UIPickerView 的数据

在 viewController 中重新加载 tableView

UITableView 在推送新的 viewController 时重新加载数据

在 ViewController 中重新加载/刷新选项卡栏项目?