简体   繁体   中英

Problems updating UITableView cell and SwiftyPickerPopover

The problem is that when I am selecting some value (in the field picker -SwiftyPickerPopover-) in a row, the action updates the same value (selected in picker) for all rows.

The code that I am using for this for the ViewController (with UITableView inside):

func btnExpenseTypePressed(at index: IndexPath) {
        var tiposGasto: [String] = [String]()
        for gasto in dataManager.expensesType {
            tiposGasto.append(gasto.tipoGasto!)
        }
        let cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier", for: index) as! ExpenseDetailCell
        StringPickerPopover.appearFrom(
        originView: cell.btnExpenseType,
        baseViewController: self,
        title: "Tipos de Gasto",
        choices: tiposGasto,
        initialRow:0,
        doneAction: { selectedRow, selectedString in
        print("Seleccion \(selectedString)")
            //self.valueSelected = selectedString
            cell.btnExpenseType.setTitle(selectedString, for: .normal)
            self.tableView.reloadData()
        } ,cancelAction: { print("cancel")}
        )
    }

    func btnCostCenterPressed(at index: IndexPath) {
        var centroCoste: [String] = [String]()
        for centro in dataManager.costsCenter {
            centroCoste.append(centro.centroCoste!)
        }
        let cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier", for: index) as! ExpenseDetailCell
        StringPickerPopover.appearFrom(
            originView: cell.btnCostCenter,
            baseViewController: self,
            title: "Centro de Coste",
            choices: centroCoste,
            initialRow:0,
            doneAction: { selectedRow, selectedString in
                print("Seleccion \(selectedString)")
                //self.valueSelected = selectedString
                cell.btnCostCenter.setTitle(selectedString, for: .normal)
                self.tableView.reloadData()
        } ,cancelAction: { print("cancel")}
        )
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell : UITableViewCell? = UITableViewCell()
        if tableView == self.tableView {
            let cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier", for: indexPath) as! ExpenseDetailCell
            cell.selectionStyle = .none
            cell.delegate = self

            debugPrint("First table load \(firstTableLoad)")
            if firstTableLoad {
                cell.btnCostCenter.setTitle(dataManager.costsCenter[0].centroCoste, for: .normal)
                cell.btnExpenseType.setTitle(dataManager.expensesType[0].tipoGasto, for: .normal)
                firstTableLoad = false
            }
            return cell
        }
        if tableView == self.tableViewImages {
            let cell = tableView.dequeueReusableCell(withIdentifier: "imagesCellIdentifier", for: indexPath) as! ExpenseImageCell
            cell.imageView?.image = UIImage(named: "imgPlaceholder")
            cell.selectionStyle = .none
            return cell
        }
        return cell!
}

The btnExpenseTypePressed and btnCostCenterPressed methods are delegate from the ExpenseDetailCell:

protocol ExpenseDetailDelegate {
    func switchChanged(at index: IndexPath)
    func amountEditedChanged(at index: IndexPath)
    func btnExpenseTypePressed(at index: IndexPath)
    func btnCostCenterPressed(at index: IndexPath)
}
class ExpenseDetailCell: UITableViewCell {
    var delegate: ExpenseDetailDelegate!
    var indexPath: IndexPath!

    var dataManager = DataManager.sharedInstance

    @IBOutlet weak var txtAmountNumber: UITextField!
    @IBOutlet weak var txtId: UITextField!
    @IBOutlet weak var txtAmountPercent: UITextField!
    @IBOutlet weak var lblTotal: UILabel!
    @IBOutlet weak var lblSeparator: UILabel!
    @IBOutlet weak var lblPercent: UILabel!
    @IBOutlet weak var btnExpenseType: UIButton!
    @IBOutlet weak var btnCostCenter: UIButton!
    @IBOutlet weak var switchID: UISwitch!

    @IBAction func btnExpenseTypePressed(_ sender: Any) {
        debugPrint("En btnExpenseTypePressed")
        self.delegate?.btnExpenseTypePressed(at: indexPath)
        debugPrint("El INDEX \(indexPath)")
    }

    @IBAction func btnCostCenterPressed(_ sender: Any) {
        debugPrint("En btnCostCenterPressed")
        self.delegate?.btnCostCenterPressed(at: indexPath)
        debugPrint("El INDEX \(indexPath)")
    }

    @IBAction func amountEditedChanged(_ sender: Any) {
        debugPrint("En amountEditedChanged")
        self.delegate?.amountEditedChanged(at: indexPath)
        lblTotal.text = txtAmountNumber.text
    }

    @IBAction func switchChanged(_ sender: Any) {
        debugPrint("En value changed")
        self.delegate?.switchChanged(at: indexPath)
        if switchID.isOn {
            debugPrint("Dentro if")
            txtId.text = ""
            txtId.isEnabled = false
        } else {
            txtId.isEnabled = true
        }
    }
}

I am using SWIFT 3.

I believe the error comes from a missunderstanding of what you want to do and what you are acctually doing.

You want: Change one value in one cell

You do: Change one value in all cells ON cell creation.

When you call: self.tableView.reloadData() in unc btnExpenseTypePressed(at index: IndexPath) iOS calls

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) again and again skipping the `firstTableLoad = false` and loading all the tableviewCells with the same value. 

You have also set the index to 0 in DataManager.costsCenter[0] which will mean that all the cells on creation will have the same value.

My suggestion: Do your changes in:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{

}

If by any chance this doesn't help you check clean the cell in :

 override func prepareForReuse()
{
    super.prepareForReuse()
}

or just set it like this:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell : UITableViewCell? = UITableViewCell()
    if tableView == self.tableView {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier", for: indexPath) as! ExpenseDetailCell
        cell.selectionStyle = .none
        cell.delegate = self
        cell.setMyCustomText("")...
        }
        return cell
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM