para numero maximo mac insertar formato filas copiar como comandos comando columnas celdas celda buscar arrastrar ios swift uitableview core-data swift3

ios - numero - ¿Cómo eliminar una celda en tableView haciendo clic en un botón en una celda? Usando coreData



numero de filas y columnas de numbers (2)

Creo una aplicación ToDo List.
Usé tableView para enumerar las tareas. Y uso una clase personalizada para celular. En Cell contentView, tengo una etiqueta y un botón hecho. Implementé con éxito la acción de hacer clic de botón en mi código. Funciona bien.

Problema

Cuando hago clic en el botón hecho, borro la última tarea añadida. Pero no el clic. Y cuando intento volver a hacer clic en el botón Hecho, no realiza ninguna acción. Cómo resolver este error

GIF agregado a continuación, haz clic en el enlace

Clase de entidad pendiente

Importar importación Importar CoreData

public class ToDo: NSManagedObject { public override func awakeFromInsert() { self.created = NSDate() } }

MainVC

import UIKit import CoreData class MainVC: UIViewController, UITableViewDelegate, UITableViewDataSource, NSFetchedResultsControllerDelegate { var controller: NSFetchedResultsController<ToDo>! @IBOutlet weak var taskTextField: CustomTextField! @IBOutlet weak var tableView: UITableView! var toDo: ToDo! override func viewDidLoad() { super.viewDidLoad() tableView.delegate = self tableView.dataSource = self // generateData() attemptFetch() } // to give view to cell func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell", for: indexPath) as! ItemCell configureCell(cell: cell, indexPath: indexPath as NSIndexPath) return cell } // custom function func configureCell(cell: ItemCell, indexPath: NSIndexPath) { let toDo = controller.object(at: indexPath as IndexPath) // call the method on the ItemCell cell.configureCell(toDo: toDo) // done button click cell.doneBtn.tag = indexPath.row cell.doneBtn.addTarget(self, action: #selector(MainVC.donePressed), for: UIControlEvents.touchUpInside) } // when select a cell func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { // it ensure it have object and atleast one object in there if let objs = controller.fetchedObjects, objs.count > 0 { let task = objs[indexPath.row] performSegue(withIdentifier: "ItemDetailsVC", sender: task) } } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "ItemDetailsVC" { if let destination = segue.destination as? ItemDetailsVC { if let task = sender as? ToDo { destination.taskDetails = task } } } } // count of cells func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // we check here if any sections then take info of them and count if let sections = controller.sections { let sectionInfo = sections[section] return sectionInfo.numberOfObjects } return 0 } // column count func numberOfSections(in tableView: UITableView) -> Int { if let sections = controller.sections { return sections.count } return 0 } // give height of a cell func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return 70 } // fetching function func attemptFetch() { // create a fetch request with fetching Entity let fetchRequest: NSFetchRequest<ToDo> = ToDo.fetchRequest() // sorting area let dateSort = NSSortDescriptor(key: "created", ascending: true) fetchRequest.sortDescriptors = [dateSort] let controller = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil) controller.delegate = self self.controller = controller // actual fetching do { try controller.performFetch() } catch { let error = error as NSError print("/(error)") } } // when tableView changes this function starts listen for changes and // it will handle that for you func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) { tableView.beginUpdates() } func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) { tableView.endUpdates() } // this function will listen for when we make change // insertion, deletion .. etc func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) { switch type { case.insert: if let indexPath = newIndexPath { tableView.insertRows(at: [indexPath], with: .fade) } break case.delete: if let indexPath = indexPath { tableView.deleteRows(at: [indexPath], with: .fade) } break case.update: if let indexPath = indexPath { let cell = tableView.cellForRow(at: indexPath) //update the cell data configureCell(cell: cell as! ItemCell, indexPath: indexPath as NSIndexPath) } break case.move: if let indexPath = indexPath { tableView.deleteRows(at: [indexPath], with: .fade) } if let indexPath = newIndexPath { tableView.insertRows(at: [indexPath], with: .fade) } break } } @IBAction func addBtnPressed(_ sender: UIButton) { if taskTextField.text != "" && taskTextField.text != nil { toDo = ToDo(context: context) if let task = taskTextField.text { toDo.title = task } ad.saveContext() taskTextField.text = "" self.tableView.reloadData() } } // done button func donePressed() { if toDo != nil { context.delete(toDo) ad.saveContext() } } func generateData() { let task = ToDo(context: context) task.title = "alwin" let task1 = ToDo(context: context) task1.title = "rambo" let task2 = ToDo(context: context) task2.title = "monisha" let task3 = ToDo(context: context) task3.title = "wounderlist" let task4 = ToDo(context: context) task4.title = "presentation" let task5 = ToDo(context: context) task5.title = "roundup" // to save data ad.saveContext() } }

ItemDetailsVC

import UIKit class ItemDetailsVC: UIViewController { var taskDetails: ToDo? @IBOutlet weak var detailsLbl: UILabel! override func viewDidLoad() { super.viewDidLoad() // to clear the <DreamLIst to < only if let topItem = self.navigationController?.navigationBar.topItem { topItem.backBarButtonItem = UIBarButtonItem(title: "", style: UIBarButtonItemStyle.plain, target: nil, action: nil) // this is execute when tap on an existing cell if taskDetails != nil { loadItemData() } } } func loadItemData() { if let task = taskDetails { detailsLbl.text = task.title } } override func viewDidLayoutSubviews() { detailsLbl.sizeToFit() } @IBAction func deletePressed(_ sender: UIBarButtonItem) { if taskDetails != nil { context.delete(taskDetails!) ad.saveContext() } _ = navigationController?.popViewController(animated: true) } }

guión gráfico, haga clic en el enlace a continuación

ItemCell

import UIKit class ItemCell: UITableViewCell { @IBOutlet weak var taskTitle: UILabel! @IBOutlet weak var doneBtn: UIButton! var toDo: ToDo? func configureCell(toDo: ToDo) { taskTitle.text = toDo.title } }


De acuerdo, entonces debes crear un punto de venta de IBAction para tu botón en ItemCell y luego crear un protocolo de esta forma:

protocol ItemDelegate { func clicked() } class ItemCell: UITableViewViewCell { var delegate : ItemDelegate? var indexPath: IndexPath? //call delegate?.clicked() where you have the gesture recogniser }

Luego en cellForRowAtIndexPath

cell.delegate = self cell.indexPath = indexPath

Luego implementa la extensión para tu clase:

extension MyTableView: ItemDelegate { func clicked(indexPath: IndexPath) { //dismiss cell for indexPath } }


OK Actualmente está configurando el selector de su botón hecho fuera de su contenedor (celda), esto es una mala práctica en general, está configurando la celda con un ToDo pero no asignando el opcional dentro de la celda, supuestamente allí para mantener una referencia a el ToDo.

En mi opinión, cambiaría esto ligeramente para que guarde la referencia al ToDo en primer lugar:

func configureCell(toDo: ToDo) { self.toDo = toDo taskTitle.text = toDo.title }

Ahora, en su celda, cree un protocolo, luego configure la celda con un ToDo y un delegado, y luego presione el botón para indicarle al delegado que se presionó su botón con el ToDo relevante ...

protocol ToDoCellDelegate: class { func toDoCellButtonPressed(todo: ToDo?) }

Ahora en su celda configure como:

func configureCell(toDo: ToDo, delegate: ToDoCellDelegate) { self.delegate = delegate self.toDo = toDo taskTitle.text = toDo.title }

y agregue una referencia al delegado en la celda:

weak var delegate: ToDoCellDelegate?

ahora cambie su selector de botones a un func dentro de la celda

func buttonPressed() { self.delegate?.cellToDoButtonPressed(toDo: toDo) }

Luego, en su VC se conforma al delegado que pasa auto en la configuración e implementa el delegado:

extension ItemDetailsVC: ToDoCellDelegate { func toDoCellButtonPress(toDo: ToDo?) { if let t = toDo { //tell context to delete todo and remove cell. } } }