Search code examples
arraysjsonswiftuitableviewindexpath

How to compare and display different array count in numberOfRowsInSection in tableview in swift


I have tableview with label, i need to display different array count in tableview for different category. for that i have taken different arrays for different category but i am unable to check condition, all the time the condition goes to outer return count in numberOfRowsInSection and i am getting all category values in tableview. I have to compare homeVC typeName with AllMakePaymentViewController category name and display accordingly in tableview.

HomeVC code for saving and selecting type for displaying category values in AllMakePaymentViewController tableview:

 func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

if itemsArray[indexPath.item].typeName == "WATER"{
    let nextViewController = self.storyboard?.instantiateViewController(withIdentifier: "AllMakePaymentViewController") as? AllMakePaymentViewController
    self.navigationController?.pushViewController(nextViewController!, animated: true)
}
else if itemsArray[indexPath.item].typeName == "ELECTRICITY"{
    let nextViewController = self.storyboard?.instantiateViewController(withIdentifier: "AllMakePaymentViewController") as? AllMakePaymentViewController
    self.navigationController?.pushViewController(nextViewController!, animated: true)
}
else if itemsArray[indexPath.item].typeName == "CASH POINT"{
    let nextViewController = self.storyboard?.instantiateViewController(withIdentifier: "AllMakePaymentViewController") as? AllMakePaymentViewController
    self.navigationController?.pushViewController(nextViewController!, animated: true)
}
else{
    AlertFun.ShowAlert(title: "", message: "will update soon..", in: self)
}
}

 //MARK:- Service-call
  func homeServiceCall(){

    do{
        let jsonObj = try JSONSerialization.jsonObject(with: respData, options: .allowFragments) as! [String: Any]
        //print("the home json is \(jsonObj)")
        let financerArray = jsonObj["financer"] as! [[String: Any]]

        for financer in financerArray {
            let id = financer["id"] as? String
            let pic = financer["icon"] as? String
            self.typeName = financer["tpe"] as! String
            KeychainWrapper.standard.set(self.typeName!, forKey: "typeName")
            var saveTypenameKey = KeychainWrapper.standard.string(forKey: "typeName")
            print("keychain typename \(KeychainWrapper.standard.set(self.typeName!, forKey: "typeName"))")
            self.itemsArray.append(JsonData(icon: pic ?? "", tpe: self.typeName ?? "", id: id ?? ""))
        }
    }
    catch {
        print("catch error")
    }
}).resume()
}

AllMakePaymentViewController code:

import UIKit

class PaymentTableViewCell: UITableViewCell{
@IBOutlet weak var pamntTypeLabel: UILabel!
}

class AllMakePaymentViewController: UIViewController {

@IBOutlet weak var tableView: UITableView!
var electricityArray = [String]()
var waterArray = [String]()
var iteamsArray = [String]()

var categoryName: String?
override func viewDidLoad() {
    super.viewDidLoad()
    allPaymentService()
}
func allPaymentService(){

    let urlStr = "https://dev.com/webservices/api.php?rquest=billermdm"
    let url = URL(string: urlStr)
    URLSession.shared.dataTask(with: url!, completionHandler: {(data, response, error) in
        guard let respData = data else {
            return
        }
        guard error == nil else {
            print("error")
            return
        }
        do{
            let jsonObj = try JSONSerialization.jsonObject(with: respData, options: .allowFragments) as! [String: Any]
            //print("the all make payment json is \(jsonObj)")
            let billerdetailsArray = jsonObj["billerdetails"] as! [[String: Any]]

            for billerdetail in billerdetailsArray {
                self.categoryName = billerdetail["bcategoryname"] as? String

                if self.categoryName == "Water"{
                    let bName = billerdetail["bname"] as? String
                    self.waterArray.append(bName ?? "")
                }
                if self.categoryName == "cashpoint"{
                    let bName = billerdetail["bname"] as? String
                    self.iteamsArray.append(bName ?? "")
                }
                if self.categoryName == "Electricity"{
                    let bName = billerdetail["bname"] as? String
                    self.electricityArray.append(bName ?? "")
                }
            }
            DispatchQueue.main.async {
                self.tableView.reloadData()
            }
        }
        catch {
            print("catch error")
        }
    }).resume()
}
}

extension AllMakePaymentViewController: UITableViewDelegate, UITableViewDataSource {

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    if categoryName == "Water"{
        return waterArray.count
    }
    if categoryName == "cashpoint"{
        return iteamsArray.count
    }
    if categoryName == "Electricity"{
        return electricityArray.count
    }
    return iteamsArray.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! PaymentTableViewCell

    if categoryName == "Electricity"{
        cell.pamntTypeLabel.text = electricityArray[indexPath.row]
    }
    if categoryName == "Water"{
        cell.pamntTypeLabel.text = waterArray[indexPath.row]
    }
    if categoryName == "cashpoint"{
        cell.pamntTypeLabel.text = iteamsArray[indexPath.row]
    }
    else
    {
        cell.pamntTypeLabel.text = iteamsArray[indexPath.row]
    }
    self.tableView.separatorStyle = .none

    return cell
}
}

How to compare homeVC typeName select from didselectItematIndex with AllMakePaymentViewController categoryname and show only selected item categoryName values in tableview label. please help me in the above code. I got stuck here from long time.


Solution

  • You need top inject the category into the nextViewControllers so it knows what data to display. To minimise the use of string literals, I'm converting them into an enum, and have changed the code to use this instead.

    enum Category: String {
      case water = "WATER"
      case electricity = "ELECTRICITY"
      case cashpoint = "CASHPOINT"
    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
      let nextViewController = self.storyboard?.instantiateViewController(withIdentifier: "AllMakePaymentViewController") as? AllMakePaymentViewController
      switch Category(rawValue: [indexPath.item].typeName) {
        case .water: nextViewcontroller.category = .water
        case .electricity: nextViewcontroller.category = .electricity
        case .cashpoint: nextViewcontroller.category = .cashpoint
        default: AlertFun.ShowAlert(title: "", message: "will update soon..", in: self)
      }
      self.navigationController?.pushViewController(nextViewController!, animated: true)
    }
    
    class AllMakePaymentViewController: UIViewController {
    
      @IBOutlet weak var tableView: UITableView!
      var electricityArray = [String]()
      var waterArray = [String]()
      var iteamsArray = [String]()
    
      var category: Category?
    
      //load data etc
    }
    
    extension AllMakePaymentViewController: UITableViewDelegate, UITableViewDataSource {
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
      guard let category = category else {return 0}
      switch category {
        case .electricity: return electricityArray.count
        case .water: return waterArray.count
        case .cashpoint: return iteamsArray.count
      }
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
      let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! PaymentTableViewCell
    
      guard let category = category else {return 0}
      switch category {
        case .electricity: cell.pamntTypeLabel.text = electricityArray[indexPath.row]
        case .water: cell.pamntTypeLabel.text = waterArray[indexPath.row]
        case .cashpoint: cell.pamntTypeLabel.text = iteamsArray[indexPath.row]
      }
        self.tableView.separatorStyle = .none
        return cell
      }
    }
    

    Note: not been able to compile this so might be small typos, but it should give you the basis for what you need. Ask if XCode throws up any syntax errors.