Search code examples
uicollectionviewswift4uicollectionviewcelluitableviewsectionheader

How to return dynamic numberOfItemsInSection in UICollectionview


I have viewForHeaderInSection in UITableView based on viewForHeaderInSection data each UITableviewCell have UICollectionView in UICollectionViewCell I have to show data for "product" and "qty" the count of each "product" and "qty" is different for each viewForHeaderInSection. I am able to achieve tableview header and cell data but I am not able to get UICollectionViewCell data based on UITableViewHeader data in the json "order_id", "order_unique_id","store_name" and "otp_store" is tableview header section data and "user_details" is tableviewcell data for uicollectionviewcell "product" and "qty"

   {
"status": "1",
"error": false,
"data": [
    {
        "order_id": "11",
        "order_unique_id": "ORDR-1001",
        "store_name": "24X7",
        "otp_store": "781103",
        "product": [
            "Product One",
            "Product Two"
        ],
        "qty": [
            "1",
            "3"
        ],
        "user_details": {
            "name": "Pankaj Ravi",
            "number": "0999889",
            "landmark": "PBH",
            "area": "Bow East",
            "pincode": "E3 9EG",
            "place": "Home"
        },
        "status": "2",
        "date": "2018-12-13",
        "time": "14:37:57"
    },
    {
        "order_id": "1",
        "order_unique_id": "ORDR-988",
        "store_name": "24X7",
        "otp_store": "957505",
        "product": [
            "Product Eight"
        ],
        "qty": [
            "1"
        ],
        "user_details": {
            "name": “Jhon”,
            "number": “999996",
            "landmark": “Ithum",
            "area": "Bow East",
            "pincode": "E3 9EG",
            "place": "Office"
        },
        "status": "0",
        "date": "2018-11-24",
        "time": "12:41:02"
    }
]
}

Code For UITableview

      func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    print(section)
    let headerCell = Bundle.main.loadNibNamed("CustomHeaderCell", owner: self, options: nil)?.first as! CustomHeaderCell
    if runnerArray.count > 0 {
        headerCell.btnHeader.setTitle("\("x " + runnerArray[section].order_unique_id)", for: UIControl.State.normal)
        var status = runnerArray[section].status
        if status == "0" {
            status = "Pending"
        } else if status == "1" {
            status = "Dispatch"
        } else {
             status = "Complete"
        }
    let lblHeaderText = status + " " + runnerArray[section].time + " , " + runnerArray[section].date
    headerCell.lblHeader.text =  lblHeaderText
    return headerCell
    } else {
        return UIView()
    }
}

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return 40
}

func numberOfSections(in tableView: UITableView) -> Int {
    return runnerArray.count
}

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

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 400
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if let cell = tableView.dequeueReusableCell(withIdentifier: "CustomTableViewCell", for: indexPath) as? CustomTableViewCell {

        cell.setDataForOTPStoreAndName(runner: runnerArray[indexPath.section])
        cell.setDataForProduct(userDetails: userDetailsArray[indexPath.section])
        cell.selectionStyle = .none
        return cell
    }
    return UITableViewCell()
}

Code For UICollectionView Cell

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    //Note:- Here i am not able to find how to return array count based on UItableviewheadersection data
    return productArray.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ProductsCollectionViewCell", for: indexPath) as? ProductsCollectionViewCell {
        cell.lblProductName.text = productArray[indexPath.row]
        return cell
    }
    return UICollectionViewCell()
}

Solution

  • you add this code to show number of header and each header add one row,then pass one section object to table cell use below code.

    import UIKit
    
    class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
    
    var dataArry : [DataObj]?
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        if let path = Bundle.main.path(forResource: "response", ofType: "json") {
            do {
                let data = try Data(contentsOf: URL(fileURLWithPath: path), options: .alwaysMapped)
                let jsonObj = try JSONDecoder().decode(Modal.self, from: data)
                self.dataArry = jsonObj.data
                print("jsonData:\(jsonObj)")
            } catch let error {
                print("parse error: \(error.localizedDescription)")
            }
        } else {
            print("Invalid filename/path.")
        }
    }
    
    func numberOfSections(in tableView: UITableView) -> Int {
        if let count = self.dataArry?.count {
            return count
        }
        return 0
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "RowCell") as? RowCell
        cell?.updateCell(dataObj: self.dataArry?[indexPath.section] ?? DataObj())
        return cell!
    }
    
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let cell = tableView.dequeueReusableCell(withIdentifier: "HeaderCell") as? HeaderCell
        cell?.textLabel?.text = dataArry?[section].store_name
        return cell
    }
    
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 60
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 200
    }
    
    }
    

    then add this code in your tableview cell class

    func updateCell(dataObj:DataObj)  {
        self.dataObj = dataObj
        collectionView.delegate = self
        collectionView.dataSource = self
        collectionView.reloadData()
    }
    
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 2
    }
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        if section == 0 {
            if let count = self.dataObj?.product?.count {
                return count
            }
        }else if section == 1 {
            if let count = self.dataObj?.qty?.count {
                return count
            }
        }
        return 0
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        if indexPath.section == 0 {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath) as? CollectionViewCell
            cell?.titlelbl.text =  self.dataObj?.product?[indexPath.row]
            return cell!
        }else if indexPath.section == 1 {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath) as?
                CollectionViewCell
            //cell?.backgroundColor = UIColor.yellow
            cell?.titlelbl.text = self.dataObj?.qty?[indexPath.row]
            return cell!
        }
        return UICollectionViewCell()
    }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: 100.0, height: 100.0)
    }
    

    }