skip to Main Content

Here is the picture of what has been implemented till now.

Image

Aim: To show the total of the the attendance of the age group in the third section in table view.

What we applied: Tried applying the label with new variable that can count the cell of the increase and decrease button function.

What is the issue: The increase and decrease button click still gets repeated in the third section of the tableview where we want only label to show the total of the attendance of the age group

What we Tried:
1.Tried applying the label with new variable that can count the cell of the increase and decrease button function, unfortunately the app crashes if ["0"] is used for new variable to implement total sum. –> var itemValue2 = ["0"] 2.Tried to implement using new controller but same thing happens.

Below is the code of the class AdditionalGuestInformationVC::

import UIKit
import ObjectiveC
import SSSpinnerButton

class AdditionalGuestInforTVCell: UITableViewCell {
        
    @IBOutlet weak var lblName: UILabel!
    @IBOutlet weak var lblDetails: UILabel!
    
    @IBOutlet var btnMinus: UIButton!
    @IBOutlet var lblValue: UILabel!
    @IBOutlet var btnPlus: UIButton!
}

class AdditionalGuestInformationVC: UIViewController, UITableViewDelegate, UITableViewDataSource {

    let section = ["Male", "Female", "total"]

    let itemsName = [["Shishu", "Baal", "Kishore", "Tarun", "Yuva", "Jyeshta"], ["Shishu", "Baalika", "Kishori", "Taruni", "Yuvati", "Jyeshtaa"], ["Total:"]]
    let itemsDetails = [["Below 5 Years - Pre-primary ", "5 to 11 Years - Primary School", "11 to 16 Years - Middle School", "17 to 25 Years - High School/College", "25 to 60 Years - Adults", ">60 Years - Senior citizen"], ["Below 5 Years - Pre-primary ", "5 to 11 Years - Primary School", "11 to 16 Years - Middle School", "17 to 25 Years - High School/College", "25 to 60 Years - Adults", ">60 Years - Senior citizen"],["Attendees"]]
    var itemValue = [["0", "0", "0", "0", "0", "0"], ["0", "0", "0", "0", "0", "0"], ["0"]]
   
    
    var dicMember = [[String:Any]]()
    
    var strDate = ""
    var utsavName = ""
    
    @IBOutlet weak var tableView: UITableView!
    @IBOutlet var lblShakhaName: UILabel!
    @IBOutlet var lblDate: UILabel!
    
    @IBOutlet var btnSubmit: SSSpinnerButton!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        self.fillData()

    }
    
    override func viewWillAppear(_ animated: Bool) {
        navigationBarDesign(txt_title: "guest_information".localized, showbtn: "back")
        self.firebaseAnalytics(_eventName: "AdditionalGuestInfoVC")
    }
    
    
    func fillData() {
        self.lblDate.text = strDate
    }
    
    @objc func onMinusClick(_ sender: UIButton) {
        
        let sectionIndex = ((sender.tag / 10) - 10)
        let rowIndex = (sender.tag % 10)

        let indexPath = NSIndexPath(row: rowIndex, section: sectionIndex)
        let cell = tableView.cellForRow(at: indexPath as IndexPath) as? AdditionalGuestInforTVCell
        
        var strVal : Int = Int((cell?.lblValue.text)!)!

        if strVal > 0 {
            strVal -= 1
        }
        self.itemValue[sectionIndex][rowIndex] = "(Int(strVal))"
        tableView.reloadRows(at:[indexPath as IndexPath], with:.automatic)

    }
    
    @objc func onPlusClick(_ sender: UIButton) {
        let sectionIndex = ((sender.tag / 10) - 10)
        let rowIndex = (sender.tag % 10)

        let indexPath = NSIndexPath(row: rowIndex, section: sectionIndex)
        let cell = tableView.cellForRow(at: indexPath as IndexPath) as? AdditionalGuestInforTVCell
        
        var strVal : Int = Int((cell?.lblValue.text)!)!

        if strVal < 99 {
            strVal += 1
        }
        self.itemValue[sectionIndex][rowIndex] = "(Int(strVal))"
        tableView.reloadRows(at:[indexPath as IndexPath], with:.automatic)
    }
    
    @IBAction func onPreviewClick(_ sender: UIButton) {
        let storyBoard = UIStoryboard(name: "Main", bundle: nil)
        let vc = storyBoard.instantiateViewController(withIdentifier: "AttendancePreviewVC") as! AttendancePreviewVC
        vc.itemsName = self.itemsName
        vc.itemsDetails = self.itemsDetails
        vc.itemValue = self.itemValue
        vc.dicMember = self.dicMember
        self.navigationController?.pushViewController(vc, animated: true)
    }
    
    @IBAction func onSubmitClick(_ sender: UIButton) {
        btnSubmit.startAnimate(spinnerType: SpinnerType.circleStrokeSpin, spinnercolor: .white, spinnerSize: 20, complete: {
            // Your code here
            self.addSankhyaAPI()
            let disableMyButton = sender as? UIButton
            disableMyButton?.isEnabled = false
        })
    }
    
    // MARK: TableView Methods
    
    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?
    {
        return self.section[section]
    }
    
    func numberOfSections(in tableView: UITableView) -> Int
    {
    // #warning Incomplete implementation, return the number of sections
        return self.section.count
    }
    
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let rect = CGRect(x: 20, y: 0, width: tableView.frame.size.width - 40, height: 60)
        let footerView = UIView(frame:rect)
        footerView.backgroundColor = UIColor.init(red: 229.0/255.0, green: 229.0/255.0, blue: 229.0/255.0, alpha: 1.0)
        
        let lblTitle = UILabel(frame: CGRect(x: 20.0, y: footerView.center.y / 2, width: 160, height: 30))
        lblTitle.text = "Guest Information"
        lblTitle.font = UIFont(name: "SourceSansPro-Regular", size: 20.0)
        lblTitle.backgroundColor = UIColor.clear
        lblTitle.textColor = UIColor.init(red: 154.0/255.0, green: 154.0/255.0, blue: 154.0/255.0, alpha: 1.0)
        
        let lblGender = UILabel(frame: CGRect(x: 30.0 + lblTitle.frame.width, y: footerView.center.y / 2, width: 80, height: 30))
        lblGender.text = self.section[section]
        lblGender.font = UIFont(name: "SourceSansPro-SemiBold", size: 16.0)
        lblGender.textColor = UIColor.black
        lblGender.backgroundColor = UIColor.init(red: 255.0/255.0, green: 230.0/255.0, blue: 190.0/255.0, alpha: 1.0)
        lblGender.layer.cornerRadius = 15.0
        lblGender.layer.masksToBounds = true
        lblGender.textAlignment = .center
        
        footerView.addSubview(lblGender)
        footerView.addSubview(lblTitle)
        return footerView
    }

    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 60  // or whatever
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.itemsName[section].count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "AdditionalGuestInforTVCell", for: indexPath) as! AdditionalGuestInforTVCell

        cell.lblName.text = self.itemsName[indexPath.section][indexPath.row]
        cell.lblDetails.text = self.itemsDetails[indexPath.section][indexPath.row]

        cell.lblValue.text = self.itemValue[indexPath.section][indexPath.row]
        cell.btnMinus.addTarget(self, action: #selector(onMinusClick(_:)), for: .touchUpInside)
        cell.btnPlus.addTarget(self, action: #selector(onPlusClick(_:)), for: .touchUpInside)
        
        let strSection : String = "(indexPath.section + 10)"
        let strRow = "(indexPath.row)"
        
        cell.btnPlus.tag = Int(strSection + strRow)!
        cell.btnMinus.tag = Int(strSection + strRow)!
        cell.lblValue.tag = Int(strSection + strRow)!
  

        return cell
    }


    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableView.automaticDimension //Choose your custom row height
    }

    
    func addSankhyaAPI() {
        
        let arrFilter : [String] = self.dicMember.filter { $0["isPresent"] as! String == "true" }.map { $0["member_id"]! as! String }
        let stringArr = arrFilter.joined(separator: " ")
        let stringArray = stringArr.replacingOccurrences(of: " ", with: ", ", options: .literal, range: nil)

        
        var parameters: [String: Any] = [:]
        parameters["user_id"] = _appDelegator.dicMemberProfile![0]["user_id"] as? String // dicUserDetails["user_id"]
        parameters["event_date"] = strDate
        parameters["org_chapter_id"] = _appDelegator.dicMemberProfile![0]["shakha_id"]
        parameters["utsav"] = utsavName
        parameters["member_id"] = stringArray
        parameters["shishu_male"] = self.itemValue[0][0]
        parameters["baal"] = self.itemValue[0][1]
        parameters["kishore"] = self.itemValue[0][2]
        parameters["tarun"] = self.itemValue[0][3]
        parameters["yuva"] = self.itemValue[0][4]
        parameters["proudh"] = self.itemValue[0][5]
        parameters["shishu_female"] = self.itemValue[1][0]
        parameters["baalika"] = self.itemValue[1][1]
        parameters["kishori"] = self.itemValue[1][2]
        parameters["taruni"] = self.itemValue[1][3]
        parameters["yuvati"] = self.itemValue[1][4]
        parameters["proudha"] = self.itemValue[1][5]
        parameters["total:"] = self.itemValue[2]
        parameters["api"] = "yes"
        
        print(parameters)
        
        APIManager.sharedInstance.callPostApi(url: APIUrl.add_sankhya, parameters: parameters) { (jsonData, error) in
            if error == nil
            {
                if let status = jsonData!["status"].int
                {
                    if status == 1
                    {
                        self.btnSubmit.stopAnimationWithCompletionTypeAndBackToDefaults(completionType: .success, backToDefaults: true, complete: {
                            // Your code here
                            if let strMessage = jsonData!["message"].string {
                                showAlert(title: APP.title, message: strMessage)
                            }
                        })
                    }else {
                        self.btnSubmit.stopAnimationWithCompletionTypeAndBackToDefaults(completionType: .fail, backToDefaults: true, complete: {
                            // Your code here
                            if let strError = jsonData!["message"].string {
                                showAlert(title: APP.title, message: strError)
                            }
                        })
                    }
                } else {
                    self.btnSubmit.stopAnimationWithCompletionTypeAndBackToDefaults(completionType: .fail, backToDefaults: true, complete: {
                        // Your code here
                        if let strError = jsonData!["message"].string {
                            showAlert(title: APP.title, message: strError)
                        }
                    })
                }
            }
        }
    }
}

2

Answers


  1. Chosen as BEST ANSWER

    Just edit the code with three functions:: To show it like below image:Solution imageFooter

    @objc func onMinusClick(_ sender: UIButton) {
        let section = (sender.tag / 10) - 10
        let row = sender.tag % 10
        var value = Int(self.itemValue[section][row]) ?? 0
        value -= 1
        if value < 0 {
            value = 0
        }
        self.itemValue[section][row] = "(value)"
        let indexPath = IndexPath(row: row, section: section)
        if let cell = self.tableView.cellForRow(at: indexPath) as? AdditionalGuestInforTVCell {
            cell.lblValue.text = self.itemValue[section][row]
        }
        calculateTotal()
    }
    
    @objc func onPlusClick(_ sender: UIButton) {
        let section = (sender.tag / 10) - 10
        let row = sender.tag % 10
        var value = Int(self.itemValue[section][row]) ?? 0
        value += 1
        self.itemValue[section][row] = "(value)"
        let indexPath = IndexPath(row: row, section: section)
        if let cell = self.tableView.cellForRow(at: indexPath) as? AdditionalGuestInforTVCell {
            cell.lblValue.text = self.itemValue[section][row]
        }
        calculateTotal()
    }
    
    
    
    func calculateTotal() {
        var total = 0
        for i in 0..<itemValue.count {
            for j in 0..<itemValue[i].count {
                total += Int(itemValue[i][j]) ?? 0
            }
        }
      
        
        let totalMembers = dicMember.count
    
        let totalMembersLabel = UILabel(frame: CGRect(x: 0, y: 0, width: tableView.frame.width, height: 80))
        totalMembersLabel.text = "Sankhya: (totalMembers)nGuest Sankhya: (total) nTotal Sankhya: (totalMembers + total)"
        totalMembersLabel.numberOfLines = 5
        totalMembersLabel.textAlignment = .center
        totalMembersLabel.font = UIFont.boldSystemFont(ofSize: 18)
        tableView.tableHeaderView = totalMembersLabel
        
        let label = UILabel(frame: CGRect(x: 0, y: 0, width: tableView.frame.width, height: 80))
        label.text = " Guest Sankhya: (total)"
        label.textAlignment = .right
        label.font = UIFont.systemFont(ofSize: 12)
        tableView.tableFooterView = label
        
        let combinedLabel = UILabel(frame: CGRect(x: 0, y: 0, width: tableView.frame.width, height: 80))
        combinedLabel.text = "Guest Sankhya: (total) "
    
        combinedLabel.textAlignment = .center
        combinedLabel.font = UIFont.boldSystemFont(ofSize: 18)
        tableView.tableFooterView = combinedLabel
    }
    

    call calculateTotal() inside tableView for viewForHeaderInSection

    //existing code
    calculateTotal()
    }
    

  2. You want to move your button actions inside your AdditionalGuestInforTVCell cell class, then use a closure to tell the controller that the value changed.

    Use a second UITableViewCell class as your "Total" cell – with two labels, so it looks like this:

    enter image description here

    When your AdditionalGuestInforTVCell cell tells the controller its value changed, update your data, get the sum of all the "items" and reload the 3rd section.

    Here’s a quick example…

    First, let’s use a struct to define your data:

    struct ItemStruct {
        var itemName: String = ""
        var itemDetails: String = ""
        var itemCount: Int = 0
    }
    

    In your controller, we’ll use a var property like this:

    // our data is now an Array of ItemStruct Arrays
    //  so we'll have one Array per section
    var myData: [[ItemStruct]] = []
    

    and we’ll initialize the data like this…

    In viewDidLoad():

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // all the normal view setup
    
        myData = getData()
    }
    
    func getData() -> [[ItemStruct]] {
        let itemsName = [
            ["Shishu", "Baal", "Kishore", "Tarun", "Yuva", "Jyeshta"],
            ["Shishu", "Baalika", "Kishori", "Taruni", "Yuvati", "Jyeshtaa"],
        ]
        let itemsDetails = [
            ["Below 5 Years - Pre-primary ", "5 to 11 Years - Primary School", "11 to 16 Years - Middle School", "17 to 25 Years - High School/College", "25 to 60 Years - Adults", ">60 Years - Senior citizen"],
            ["Below 5 Years - Pre-primary ", "5 to 11 Years - Primary School", "11 to 16 Years - Middle School", "17 to 25 Years - High School/College", "25 to 60 Years - Adults", ">60 Years - Senior citizen"],
        ]
        
        var tmpArray: [[ItemStruct]] = []
        
        // let's fill our data with names and details
        for (names, details) in zip(itemsName, itemsDetails) {
            var secData: [ItemStruct] = []
            for i in 0..<names.count {
                let d = ItemStruct(itemName: names[i], itemDetails: details[i], itemCount: 0)
                secData.append(d)
            }
            tmpArray.append(secData)
        }
        
        return tmpArray
    
    }
    

    Here’s a complete, runnable example. We create everything via code – no @IBOutlet or @IBAction connections – so all you need to do is assign the custom class of a plain UIViewController as AdditionalGuestInformationVC. I’ve tried to include enough in-line comments in the code to make things clear:

    struct ItemStruct {
        var itemName: String = ""
        var itemDetails: String = ""
        var itemCount: Int = 0
    }
    
    
    class TotalCell: UITableViewCell {
        
        var lblTitle = UILabel()
        var lblValue = UILabel()
        
        override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
            super.init(style: style, reuseIdentifier: reuseIdentifier)
            commonInit()
        }
        required init?(coder: NSCoder) {
            super.init(coder: coder)
            commonInit()
        }
        func commonInit() {
            
            // label properties
            lblTitle.text = "Total Attendees:"
            lblValue.textAlignment = .center
            
            // add views to contentView
            [lblTitle, lblValue].forEach { v in
                v.translatesAutoresizingMaskIntoConstraints = false
                contentView.addSubview(v)
            }
            
            // use content view's defaualt margins
            let g = contentView.layoutMarginsGuide
            
            // this avoids autolayout complaints
            let c = lblTitle.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: 0.0)
            c.priority = .required - 1
            
            NSLayoutConstraint.activate([
                
                // Name label Top / Leading
                lblTitle.topAnchor.constraint(equalTo: g.topAnchor, constant: 0.0),
                lblTitle.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 0.0),
                lblTitle.heightAnchor.constraint(equalToConstant: 50.0),
                c,
                
                // Value label Trailing
                lblValue.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: 0.0),
                
                lblValue.widthAnchor.constraint(equalToConstant: 40.0),
                
                // vertically center Value label
                lblValue.centerYAnchor.constraint(equalTo: g.centerYAnchor),
                
            ])
            
        }
        
        func fillData(_ value: Int) {
            lblValue.text = "(value)"
        }
        
    }
    
    class AdditionalGuestInforTVCell: UITableViewCell {
    
        // closure to inform the controller that the count changed
        var countChanged: ((UITableViewCell, Int) -> ())?
        
        var lblName = UILabel()
        var lblDetails = UILabel()
        
        var btnMinus = UIButton()
        var lblValue = UILabel()
        var btnPlus = UIButton()
        
        // we'll automatically update the value label when the count changes
        var currentItemCount: Int = 0 {
            didSet {
                lblValue.text = "(currentItemCount)"
            }
        }
        
        @objc func minusTap() {
            if currentItemCount > 0 {
                // decrement current count
                currentItemCount -= 1
                
                // inform the controller
                countChanged?(self, currentItemCount)
            }
        }
        
        @objc func plusTap() {
            // increment current count
            currentItemCount += 1
            
            // inform the controller
            countChanged?(self, currentItemCount)
        }
        
        // we'll fill the labels from our data struct object
        func fillData(_ data: ItemStruct) {
            lblName.text = "(data.itemName)"
            lblDetails.text = "(data.itemDetails)"
            self.currentItemCount = data.itemCount
        }
        
        override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
            super.init(style: style, reuseIdentifier: reuseIdentifier)
            commonInit()
        }
        required init?(coder: NSCoder) {
            super.init(coder: coder)
            commonInit()
        }
        func commonInit() {
            
            // label properties
            lblDetails.font = .systemFont(ofSize: 14.0)
            lblDetails.textColor = .gray
            lblDetails.numberOfLines = 0
            
            lblValue.textAlignment = .center
            
            // button titles
            btnMinus.setTitle("-", for: [])
            btnPlus.setTitle("+", for: [])
            
            // button style
            [btnMinus, btnPlus].forEach { b in
                b.setTitleColor(.black, for: .normal)
                b.setTitleColor(.lightGray, for: .highlighted)
                b.layer.cornerRadius = 6
                b.layer.borderWidth = 1
                b.layer.borderColor = UIColor.lightGray.cgColor
            }
            
            // add views to contentView
            [lblName, lblDetails, btnMinus, lblValue, btnPlus].forEach { v in
                v.translatesAutoresizingMaskIntoConstraints = false
                contentView.addSubview(v)
            }
            
            // use content view's defaualt margins
            let g = contentView.layoutMarginsGuide
            
            // this avoids autolayout complaints
            let c = lblDetails.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: 0.0)
            c.priority = .required - 1
            
            NSLayoutConstraint.activate([
                
                // Name label Top / Leading
                lblName.topAnchor.constraint(equalTo: g.topAnchor, constant: 0.0),
                lblName.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 0.0),
                
                // Details label Top (to Name label Bottom) / Leading / Bottom
                lblDetails.topAnchor.constraint(equalTo: lblName.bottomAnchor, constant: 6.0),
                lblDetails.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 0.0),
                c,
    
                // plus button Trailing
                btnPlus.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: 0.0),
                
                // Value label Trailing (to Plus button Leading)
                lblValue.trailingAnchor.constraint(equalTo: btnPlus.leadingAnchor, constant: 0.0),
                
                // Minus button Trailing (to Value label Leading)
                btnMinus.trailingAnchor.constraint(equalTo: lblValue.leadingAnchor, constant: 0.0),
                
                // buttons and Value label centered vertically
                btnPlus.centerYAnchor.constraint(equalTo: g.centerYAnchor),
                lblValue.centerYAnchor.constraint(equalTo: g.centerYAnchor),
                btnMinus.centerYAnchor.constraint(equalTo: g.centerYAnchor),
                
                btnMinus.widthAnchor.constraint(equalToConstant: 40.0),
                btnPlus.widthAnchor.constraint(equalTo: btnMinus.widthAnchor),
                lblValue.widthAnchor.constraint(equalTo: btnMinus.widthAnchor),
    
                // Details label Trailing ("right edge")
                lblDetails.trailingAnchor.constraint(equalTo: btnMinus.leadingAnchor, constant: -8.0),
                
            ])
    
            btnMinus.addTarget(self, action: #selector(minusTap), for: .touchUpInside)
            btnPlus.addTarget(self, action: #selector(plusTap), for: .touchUpInside)
    
        }
        
    }
    
    class AdditionalGuestInformationVC: UIViewController, UITableViewDelegate, UITableViewDataSource {
        
        let section = ["Male", "Female", "Total"]
        
        var tableView: UITableView!
        
        var myData: [[ItemStruct]] = []
    
        func getData() -> [[ItemStruct]] {
            let itemsName = [
                ["Shishu", "Baal", "Kishore", "Tarun", "Yuva", "Jyeshta"],
                ["Shishu", "Baalika", "Kishori", "Taruni", "Yuvati", "Jyeshtaa"],
            ]
            let itemsDetails = [
                ["Below 5 Years - Pre-primary ", "5 to 11 Years - Primary School", "11 to 16 Years - Middle School", "17 to 25 Years - High School/College", "25 to 60 Years - Adults", ">60 Years - Senior citizen"],
                ["Below 5 Years - Pre-primary ", "5 to 11 Years - Primary School", "11 to 16 Years - Middle School", "17 to 25 Years - High School/College", "25 to 60 Years - Adults", ">60 Years - Senior citizen"],
            ]
            
            var tmpArray: [[ItemStruct]] = []
            
            // let's fill our data with names and details
            for (names, details) in zip(itemsName, itemsDetails) {
                var secData: [ItemStruct] = []
                for i in 0..<names.count {
                    let d = ItemStruct(itemName: names[i], itemDetails: details[i], itemCount: 0)
                    secData.append(d)
                }
                tmpArray.append(secData)
            }
            
            return tmpArray
    
        }
        
        override func viewDidLoad() {
            super.viewDidLoad()
            
            view.backgroundColor = .systemGreen
            
            tableView = UITableView(frame: .zero, style: .insetGrouped)
            
            tableView.translatesAutoresizingMaskIntoConstraints = false
            view.addSubview(tableView)
            
            let g = view.safeAreaLayoutGuide
            NSLayoutConstraint.activate([
                
                // Top / Leading / Trailing inset by 20-points (so we can see the table frame)
                tableView.topAnchor.constraint(equalTo: g.topAnchor, constant: 20.0),
                tableView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
                tableView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),
                
                // let's leave some space at the bottom
                tableView.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: -80.0),
                
            ])
            
            // register the "input" cells
            tableView.register(AdditionalGuestInforTVCell.self, forCellReuseIdentifier: "AdditionalGuestInforTVCell")
            // register the "Total" cell
            tableView.register(TotalCell.self, forCellReuseIdentifier: "totalCell")
            
            tableView.dataSource = self
            tableView.delegate = self
    
            myData = getData()
            
        }
    
        // MARK: TableView Methods
        
        func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
            return self.section[section]
        }
        
        func numberOfSections(in tableView: UITableView) -> Int {
            // add 1 for the Total section
            return myData.count + 1
        }
        
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            // if it's the last section, it's the Total section
            if section == myData.count {
                return 1
            }
            return myData[section].count
        }
        
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            
            // if it's the last section, it's the Total section
            if indexPath.section == myData.count {
                let cell = tableView.dequeueReusableCell(withIdentifier: "totalCell", for: indexPath) as! TotalCell
                
                // get the total of values from all data
                var total: Int = 0
                for i in 0..<self.myData.count {
                    total += self.myData[i].reduce(0) { $0 + $1.itemCount }
                }
                
                cell.fillData(total)
                
                return cell
            }
            
            // it's not the last section
            
            let cell = tableView.dequeueReusableCell(withIdentifier: "AdditionalGuestInforTVCell", for: indexPath) as! AdditionalGuestInforTVCell
            cell.fillData(myData[indexPath.section][indexPath.row])
            
            // add closure
            cell.countChanged = { [weak self] aCell, aValue in
                guard let self = self,
                      let thisCell = aCell as? AdditionalGuestInforTVCell,
                      let idxPath = self.tableView.indexPath(for: thisCell)
                else { return }
                
                // update the data
                self.myData[idxPath.section][idxPath.row].itemCount = aValue
                
                // reload the last section (the "Total" section)
                self.tableView.reloadSections([self.myData.count], with: .none)
                
            }
            return cell
    
        }
        
    }
    

    and it should look like this when running:

    enter image description here enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search