-1

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.

Swift
  • 1,074
  • 12
  • 46
  • Too long questions will not getting too much attentions. – Mojtaba Hosseini Oct 31 '19 at 11:09
  • You need to just post relevant bits of code - all the loading from JSON isn't relevant to the question. However posted an outline answer below that should provide you with enough to get going. – flanker Oct 31 '19 at 11:21

1 Answers1

1

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.

flanker
  • 3,840
  • 1
  • 12
  • 20
  • `didSelectItemAt` in homVC and `Category ` in anotherVC.. getting few errors so can i share my code through github link so u can run and solve the issue.. i got stuck here from long time – Swift Oct 31 '19 at 12:01
  • @swift Sorry, but I don't have the time to debug your entire codebase. If you have specific problems you can ask them here and people will help, but you do need to have made an effort yourself first. If the above code has solved the specific question asked, please can you mark it as accepted, or else comment explaining why it hasn't. – flanker Oct 31 '19 at 12:25
  • okay, no problem, actually i need to compare homeVC typeName with AllMakePaymentViewController categoryName and display related values in tableview. how to do that? – Swift Oct 31 '19 at 12:40
  • how to compare oneVC value in otherVC – Swift Oct 31 '19 at 12:41
  • You need to inject the value into the new VC after you instantiate it but before you push it, as in the example above, where it is comparing the category value from the original VC in the AllMakePaymentViewController – flanker Oct 31 '19 at 12:45
  • You understood my issue perfectly, its also a correct answer, but for better code efficiency can we add all categoryName array in single array(means electricityArray, waterArray, iteamsArray instead of one single array) in AllMakePaymentViewController because i have so many other categories also thats why – Swift Oct 31 '19 at 13:59
  • for the same your above code can we do all in single case dynamically because for all cases from home we're pushing same viewcontroller – Swift Oct 31 '19 at 14:27
  • hey i will accept ur answer, if u solve my commented issue ie., all in single case that will be helpful to me.. if u do, i'll upvote as well – Swift Oct 31 '19 at 15:39
  • I don't understand your comment. if you have other categories just add them to the enum. If you just want to inject one link into each VC you'll need to structure your app properly and hold the data in a datamodel class, then you can just inject the reference to the model (or for even better architecture, the model controller that accesses the datamodel). – flanker Oct 31 '19 at 15:49
  • I have label in AllMakePaymentViewController.. how to show homeVC selected item text means category values like(WATER, ELECTRICITY, CASHPOINT) from didSelectItemAt to AllMakePaymentViewController label – Swift Nov 01 '19 at 09:45
  • the enum passes the selection from the homeVC to AllMAkePayments. Use it's rawValue if you want the original text, or just in a switch statement. If it's not making sense it might be worth doing some research on enums and dependency injection. There's a lot of well written material available so no point me recreating it. – flanker Nov 02 '19 at 01:07
  • Hey thank you so much for your help.. i am able to do remaining work.. upvote for you!! – Swift Nov 04 '19 at 06:30