Best regard. I work on an application which has a list of items, each item in the list is composed of a custom cell (TableViewCell) which contains 1 textfield and several labels. I'm trying to capture the value change event of the textfield in the cell. So far I have this code but I can't capture the event... Any ideas?
TableViewCell
class TableViewCell: UITableViewCell, UITextFieldDelegate{
@IBOutlet weak var imagen: UIImageView!
@IBOutlet weak var producto: UILabel!
@IBOutlet weak var precio: UILabel!
@IBOutlet weak var cantidad: UITextField?
@IBOutlet weak var stock: UILabel!
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
cantidad?.delegate = self
self.contentView.addSubview(cantidad!)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
@IBAction func txtCantidad_onChange(_ sender: Any) {
if cantidad?.text != "0" {
print("Cambio con valor != a 0")
}else{
print("Cambio con valor 0")
}
}
}
The code shown above is just an example, but I actually want to execute all the code from the didSelectRowAt method of the tableView
The table startup code is housed in a separate ViewController
ViewController
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrProductosDetalle.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let celda = Bundle.main.loadNibNamed("ProductoViewCell", owner: self, options: nil)?.first as! ProductoViewCell
let aux = arrProductos[indexPath.row] as! Producto
let dataDecoded:NSData = NSData(base64Encoded: aux.imagen, options: NSData.Base64DecodingOptions(rawValue: 0))!
let decodedimage:UIImage = UIImage(data: dataDecoded as Data)!
celda.imagen.image = decodedimage
celda.producto.text = aux.nombre
celda.precio.text = "Precio: $\(Formato().Double2String(valor: aux.precioVenta))"
celda.stock.text = "En stock \((arrProductos[indexPath.row] as! Producto).stock)"
return celda
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let celda = tableView.cellForRow(at: indexPath)
let aux = arrProductos[indexPath.row] as! Producto
if (celda?.isSelected)! {
if (celda as! ProductoViewCell).cantidad?.text != "" {
if ((celda as! ProductoViewCell).cantidad?.text?.isInt)! && (celda as! ProductoViewCell).cantidad?.text != "0"{
if Int(((celda as! ProductoViewCell).cantidad?.text)!)! <= aux.stock
{
let nuevo: PedidoDetalle = PedidoDetalle()
nuevo.idProducto = aux.id;
nuevo.precioUnitario = aux.precioVenta
nuevo.cantidad = Int(((celda as! ProductoViewCell).cantidad?.text)!)!
nuevo.precioSubtotal = (nuevo.precioUnitario * Double(nuevo.cantidad))
nuevo.idParametrizacion = 1
arrProductosDetalle.add(nuevo)
lstPedidoDetalle.reloadData()
lblTotal.text = Formato().Double2String(valor: calcularTotal())
celda?.accessoryType = .checkmark
}else{
celda?.isSelected = false
Mensaje().mensaje(controller: self,texto: "El stock no es suficiente")
}
}else{
celda?.isSelected = false
(celda as! ProductoViewCell).cantidad?.text = ""
Mensaje().mensaje(controller: self, texto: "Tipo de dato no valido o valor no valido")
}
}else{
celda?.isSelected = false
Mensaje().mensaje(controller: self,texto: "Primero defina la cantidad de este producto")}
}else{
}
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
if tableView == lstPedidos{
let celda = tableView.cellForRow(at: indexPath)
let aux = arrProductos[indexPath.row] as! Producto
let nuevo: PedidoDetalle = PedidoDetalle()
nuevo.idProducto = aux.id;
nuevo.precioUnitario = aux.precioVenta
nuevo.cantidad = Int(((celda as! ProductoViewCell).cantidad?.text)!)!
nuevo.precioSubtotal = (nuevo.precioUnitario * Double(nuevo.cantidad))
//arrPedidoProducto.add(nuevo)
for item in arrProductosDetalle
{
let aux = item as! PedidoDetalle
if(aux.idProducto == nuevo.idProducto && aux.cantidad == nuevo.cantidad)
{
arrProductosDetalle.remove(aux)
}
}
//arrProductosDetalle.removeObject(identicalTo: nuevo)
(celda as! ProductoViewCell).cantidad?.text = ""
celda?.accessoryType = .none
lstPedidoDetalle.reloadData()
lblTotal.text = Formato().Double2String(valor: calcularTotal())
}
}
Sure there are more ways to do it but this is what I would do.
First remove the txtCantidad_onChange function from the cell class and put it in the viewController
Second, add the target to the UITextField when each cell is created and add a tag corresponding to the cell line (row) to facilitate work later
Third, modify the txtCantidad_onChange function so that it modifies the Product object that corresponds to it (we know which one it is thanks to the tag that we added before). Since you are dealing with objects, what you modify in aux will affect the original object in the list.
In the didSelectRow function you can avoid writing
celda as! ProductoViewCell
so many times if you put it at the beginning